寻求简历解析思路

KsonJsy 2014-07-08 11:03:38
参考:http://www.cvanalyze.com/demo
可以将不同格式的(word,pdf,txt,html等)简历解析成统一的格式,从简历文本中提取出候选人的结构化字段,包括姓名,性别,年龄,联系方式,毕业院校,工作单位,求职意向...等等。并将简历导入数据库
1.工作经验等关键词,可能不同简历中有不同的说法,内容有可能是文本,也可能是表格。
2.如何对关键词进行提取?算法之类的怎么弄?
该怎么做?
麻烦大神给点思路。
...全文
422 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
青埂峰 2015-04-01
  • 打赏
  • 举报
回复
这个做出来了吗?或者有什么思路?
於黾 2014-07-09
  • 打赏
  • 举报
回复
有些人写的简历,人看着都费劲,别说让机器读了 真能读出来,你程序比人智商高.
於黾 2014-07-09
  • 打赏
  • 举报
回复
说实话,这个有点难 首先文件可以采用TXT,WORD,EXCEL,PDF等 TXT还可以有4种编码,WORD还可以是DOC和HTM,EXCEL有XLS,XLSX,CSV 然后格式上,哪个在前,哪个在后,都好说. 关键是可能把许多信息写到一行,也可能分行,也可能一条信息分2行,比如上面是名称,下面是内容 也可能左边内容,右边名称,或者根本不分内容和名称都写一起 名称也可能各种各样的,比如名字/姓名/Name/姓:XX,名:XXX 总之想实现任何格式都能读取不现实,你真的编出来,就可以称之为人工智能了 总要符合一定的规范才行,不能想咋写咋写
KsonJsy 2014-07-09
  • 打赏
  • 举报
回复
引用 7 楼 jlmd_2469717682 的回复:
将Excel数据表读取到文本文件 private void btn_Select_Click(object sender, EventArgs e) { openFileDialog1.Filter = "Excel文件|*.xls";//设置打开文件筛选器 openFileDialog1.Title = "选择Excel文件";//设置打开对话框标题 openFileDialog1.Multiselect = false;//设置打开对话框中只能单选 if (openFileDialog1.ShowDialog() == DialogResult.OK)//判断是否选择了文件 { txt_Path.Text = openFileDialog1.FileName;//在文本框中显示Excel文件名 CBoxBind();//对下拉列表进行数据绑定 } } private void btn_Txt_Click(object sender, EventArgs e) { //连接Excel数据库 OleDbConnection olecon = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txt_Path.Text + ";Extended Properties=Excel 8.0"); olecon.Open();//打开数据库连接 OleDbDataAdapter oledbda = new OleDbDataAdapter("select * from [" + cbox_SheetName.Text + "$]", olecon);//从工作表中查询数据 DataSet myds = new DataSet();//实例化数据集对象 oledbda.Fill(myds);//填充数据集 StreamWriter SWriter = new StreamWriter(cbox_SheetName.Text + ".txt", false, Encoding.Default);//实例化写入流对象 string P_str_Content = "";//存储读取的内容 for (int i = 0; i < myds.Tables[0].Rows.Count; i++)//遍历数据集中表的行数 { for (int j = 0; j < myds.Tables[0].Columns.Count; j++)//遍历数据集中表的列数 { P_str_Content += myds.Tables[0].Rows[i][j].ToString() + " ";//记录当前遍历到的内容 } P_str_Content += Environment.NewLine;//字符串换行 } SWriter.Write(P_str_Content);//先文本文件中写入内容 SWriter.Close();//关闭写入流对象 SWriter.Dispose();//释放写入流所占用的资源 MessageBox.Show("已经将" + cbox_SheetName.Text + "工作表中的数据成功写入到了文本文件中", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void CBoxBind()//对下拉列表进行数据绑定 { cbox_SheetName.Items.Clear();//清空下拉列表项 //连接Excel数据库 OleDbConnection olecon = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txt_Path.Text + ";Extended Properties=Excel 8.0"); olecon.Open();//打开数据库连接 System.Data.DataTable DTable = olecon.GetSchema("Tables");//实例化表对象 DataTableReader DTReader = new DataTableReader(DTable);//实例化表读取对象 while (DTReader.Read())//循环读取 { string P_str_Name = DTReader["Table_Name"].ToString().Replace('$', ' ').Trim();//记录工作表名称 if (!cbox_SheetName.Items.Contains(P_str_Name))//判断下拉列表中是否已经存在该工作表名称 cbox_SheetName.Items.Add(P_str_Name);//将工作表名添加到下拉列表中 } DTable = null;//清空表对象 DTReader = null;//清空表读取对象 olecon.Close();//关闭数据库连接 cbox_SheetName.SelectedIndex = 0;//设置下拉列表默认选项为第一项 }
你这仅仅是读取EXCEL的东西而已;
jlmd_2469717682 2014-07-09
  • 打赏
  • 举报
回复
将Excel数据表读取到文本文件 private void btn_Select_Click(object sender, EventArgs e) { openFileDialog1.Filter = "Excel文件|*.xls";//设置打开文件筛选器 openFileDialog1.Title = "选择Excel文件";//设置打开对话框标题 openFileDialog1.Multiselect = false;//设置打开对话框中只能单选 if (openFileDialog1.ShowDialog() == DialogResult.OK)//判断是否选择了文件 { txt_Path.Text = openFileDialog1.FileName;//在文本框中显示Excel文件名 CBoxBind();//对下拉列表进行数据绑定 } } private void btn_Txt_Click(object sender, EventArgs e) { //连接Excel数据库 OleDbConnection olecon = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txt_Path.Text + ";Extended Properties=Excel 8.0"); olecon.Open();//打开数据库连接 OleDbDataAdapter oledbda = new OleDbDataAdapter("select * from [" + cbox_SheetName.Text + "$]", olecon);//从工作表中查询数据 DataSet myds = new DataSet();//实例化数据集对象 oledbda.Fill(myds);//填充数据集 StreamWriter SWriter = new StreamWriter(cbox_SheetName.Text + ".txt", false, Encoding.Default);//实例化写入流对象 string P_str_Content = "";//存储读取的内容 for (int i = 0; i < myds.Tables[0].Rows.Count; i++)//遍历数据集中表的行数 { for (int j = 0; j < myds.Tables[0].Columns.Count; j++)//遍历数据集中表的列数 { P_str_Content += myds.Tables[0].Rows[i][j].ToString() + " ";//记录当前遍历到的内容 } P_str_Content += Environment.NewLine;//字符串换行 } SWriter.Write(P_str_Content);//先文本文件中写入内容 SWriter.Close();//关闭写入流对象 SWriter.Dispose();//释放写入流所占用的资源 MessageBox.Show("已经将" + cbox_SheetName.Text + "工作表中的数据成功写入到了文本文件中", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void CBoxBind()//对下拉列表进行数据绑定 { cbox_SheetName.Items.Clear();//清空下拉列表项 //连接Excel数据库 OleDbConnection olecon = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txt_Path.Text + ";Extended Properties=Excel 8.0"); olecon.Open();//打开数据库连接 System.Data.DataTable DTable = olecon.GetSchema("Tables");//实例化表对象 DataTableReader DTReader = new DataTableReader(DTable);//实例化表读取对象 while (DTReader.Read())//循环读取 { string P_str_Name = DTReader["Table_Name"].ToString().Replace('$', ' ').Trim();//记录工作表名称 if (!cbox_SheetName.Items.Contains(P_str_Name))//判断下拉列表中是否已经存在该工作表名称 cbox_SheetName.Items.Add(P_str_Name);//将工作表名添加到下拉列表中 } DTable = null;//清空表对象 DTReader = null;//清空表读取对象 olecon.Close();//关闭数据库连接 cbox_SheetName.SelectedIndex = 0;//设置下拉列表默认选项为第一项 }
  • 打赏
  • 举报
回复
模板,规范,规定死了会简单很多
j34jyj94ksigj4j 2014-07-08
  • 打赏
  • 举报
回复
做过简历管理软件,支持纯文本和html解析,不过简历解析的思路与算法不过不能说,测试了一下你提供的那个解析器,解析准确率比我的解析器差多了
csdn_aspnet 2014-07-08
  • 打赏
  • 举报
回复
真没用过 /// <summary> /// 根据模板和一个DataTable得到一个解析字符串 /// </summary> /// <param name="template">字符串模板</param> /// <param name="dt">一个DataTable</param> /// <returns>返回一个解析模板后的字符串</returns> public static string Render(string template, DataTable dt) { if (dt == null || dt.Rows.Count < 1) { return ""; } StringBuilder sb = new StringBuilder(1000); List<string> arr; List<string> columns; Analyze(template, out arr, out columns); int i; foreach (DataRow row in dt.Rows) { i = 0; for (; i < columns.Count; i++) { sb.Append(arr[i]); sb.Append(row[columns[i]].ToString()); } if (i < arr.Count) { sb.Append(arr[i]); } } return sb.ToString(); } /// <summary> /// 根据模板和一个DataTable得到一个解析字符串 /// </summary> /// <param name="template">字符串模板</param> /// <param name="dt">一个DataTable</param> /// <returns>返回一个解析模板后的字符串</returns> /// <param name="rowCount">定义个行数,每隔此行数时调用传入的委托</param> /// <param name="act">一个处理输出字符串的委托</param> /// <returns></returns> public static string Render(string template, DataTable dt,int rowCount,Action<StringBuilder> act) { if (dt == null || dt.Rows.Count < 1) { return ""; } StringBuilder sb = new StringBuilder(1000); List<string> arr; List<string> columns; Analyze(template, out arr, out columns); int i; //计算出每隔多少行调用一次act rowCount = rowCount > 0 ? rowCount : dt.Rows.Count + 1; int rowNum = 0; foreach (DataRow row in dt.Rows) { rowNum++; i = 0; for (; i < columns.Count; i++) { sb.Append(arr[i]); sb.Append(row[columns[i]].ToString()); } if (i < arr.Count) { sb.Append(arr[i]); } if (rowNum % rowCount == 0) { act(sb); } } return sb.ToString(); } /// <summary> /// 根据模板和一个泛型实体集合得到一个解析字符串 /// </summary> /// <typeparam name="T">实体类型</typeparam> /// <param name="template">字符串模板</param> /// <param name="list">实体集合</param> /// <returns>返回一个解析模板后的字符串</returns> public static string Render<T>(string template, List<T> list) { if (list == null || list.Count < 1) { return ""; } StringBuilder sb = new StringBuilder(1000); List<string> arr; List<string> columns; Analyze(template, out arr, out columns); int i; Type type = typeof(T); foreach (T item in list) { i = 0; for (; i < columns.Count; i++) { sb.Append(arr[i]); sb.Append(GetValue(type, item, columns[i])); } if (i < arr.Count) { sb.Append(arr[i]); } } return sb.ToString(); } /// <summary> /// 对一个字符串模板进行分析 /// </summary> /// <param name="template">字符串模板</param> /// <param name="arr">存储除开列名的其他文本的集合</param> /// <param name="columns">存储列名的集合</param> static void Analyze(string template, out List<string> arr, out List<string> columns) { arr = new List<string>(); columns = new List<string>(); int previousEndIndex = 0; //找到{xxx} int startIndex = template.IndexOf('{'); int endIndex = template.IndexOf('}'); while (startIndex != -1) { //存储上一个}和现在搜索到的{之间的字符串,如果是第一次搜索到{,那么previousEndIndex=0则存储的是字符串起始到第一个{之间的字符串 arr.Add(template.Substring(previousEndIndex, startIndex - previousEndIndex)); //存储列名 columns.Add(template.Substring(startIndex + 1, endIndex - startIndex - 1)); startIndex++; endIndex++; previousEndIndex = endIndex; startIndex = template.IndexOf('{', startIndex); endIndex = template.IndexOf('}', endIndex); } //如果模板不是以}结尾,说明后面还有字符串 if (previousEndIndex < template.Length) { arr.Add(template.Substring(previousEndIndex)); } //方法执行到此处,arr.Length==columns.Length或者arr.Length==columns.Length+1 } /// <summary> /// 根据一个实体类型,实体实例和属性名,获取属性值 /// </summary> /// <param name="type">实体类型</param> /// <param name="item">实体实例</param> /// <param name="attrName">属性吗</param> /// <returns></returns> static string GetValue(Type type, object item, string attrName) { PropertyInfo property = type.GetProperty(attrName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance); object obj = property.GetValue(item, null); if (obj != null) { return obj.ToString(); } return ""; } /// <summary> /// 根据模板,使用正则匹配然后替换输出字符串 /// </summary> /// <param name="template"></param> /// <param name="dt"></param> /// <returns></returns> public static string RenderTemplate(string template, DataTable dt) { StringBuilder sb = new StringBuilder(1000); MatchCollection matches = reg.Matches(template); string rowStr = template; foreach (DataRow row in dt.Rows) { rowStr = template; foreach (Match match in matches) { rowStr = rowStr.Replace(match.Value, row[match.Groups[1].Value].ToString()); } sb.Append(rowStr); sb.Append("\n"); } return sb.ToString(); }
KsonJsy 2014-07-08
  • 打赏
  • 举报
回复
没用人么,求大神
KsonJsy 2014-07-08
  • 打赏
  • 举报
回复
引用 5 楼 AndroidJavaApp 的回复:
简历解析器就是文本解析器,对关键词及其内容进行分拣,由于目标格式变化多样,首先要创建一个通用解析器,通用解析器的解析准确度是衡量解析能力最重要的指标,对于某些不规范或完全不规范的内容,应建立特定解析器进行辅助解析。 这个演示网站的通用解析器完全不行,他们提供的简历范本的解析都是特定解析,也就是根据简历的格式(如:51job、智联招聘等简历格式)写死规则的,一旦格式变化,就失效了。
谢谢
j34jyj94ksigj4j 2014-07-08
  • 打赏
  • 举报
回复
简历解析器就是文本解析器,对关键词及其内容进行分拣,由于目标格式变化多样,首先要创建一个通用解析器,通用解析器的解析准确度是衡量解析能力最重要的指标,对于某些不规范或完全不规范的内容,应建立特定解析器进行辅助解析。 这个演示网站的通用解析器完全不行,他们提供的简历范本的解析都是特定解析,也就是根据简历的格式(如:51job、智联招聘等简历格式)写死规则的,一旦格式变化,就失效了。
KsonJsy 2014-07-08
  • 打赏
  • 举报
回复
引用 3 楼 AndroidJavaApp 的回复:
做过简历管理软件,支持纯文本和html解析,不过简历解析的思路与算法不过不能说,测试了一下你提供的那个解析器,解析准确率比我的解析器差多了
不可以指导一下吗?你做的比那个还强?这么厉害,可以提供一下思路吗?

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧