Commit 72141584 authored by 李文光's avatar 李文光

fix: 识别简历顶部独立成行的求职岗位

parent 542a4008
...@@ -238,6 +238,34 @@ def infer_name(text: str, filename: str) -> str: ...@@ -238,6 +238,34 @@ def infer_name(text: str, filename: str) -> str:
return "" return ""
_JOB_TITLE_SUFFIX = re.compile(
r"(?:专员|工程师|经理|总监|顾问|助理|主管|运营|设计师|分析师|代表|主任|编辑|记者|律师|"
r"医生|护士|会计|出纳|销售|采购|市场|人事|行政|文员|客服|讲师|教练|专家|规划师|架构师|测试|开发)$"
)
def _infer_job_from_standalone_line(text: str) -> str:
"""从简历顶部独立成行的岗位名(如"销售支持专员")识别求职岗位。"""
for line in text.splitlines():
line = line.strip()
if not line:
continue
# 遇到正文区块即停止,岗位名通常出现在简历顶部
if re.match(
r"^(?:教育背景|教育经历|学习经历|工作经历|项目经历|实习经历|自我评价|技能|证书|获奖|荣誉)", line
):
break
if len(line) < 3 or len(line) > 16:
continue
if re.search(r"[。,、;:()()]", line):
continue
if not re.fullmatch(r"[一-龥A-Za-z0-9·\- ]+", line):
continue
if _JOB_TITLE_SUFFIX.search(line):
return line
return ""
def infer_job(text: str) -> str: def infer_job(text: str) -> str:
explicit = first_match([ explicit = first_match([
r"(?:求职意向|应聘岗位|目标岗位|应聘职位|求职岗位)[::\s]+([^\n]{2,24})", r"(?:求职意向|应聘岗位|目标岗位|应聘职位|求职岗位)[::\s]+([^\n]{2,24})",
...@@ -255,7 +283,7 @@ def infer_job(text: str) -> str: ...@@ -255,7 +283,7 @@ def infer_job(text: str) -> str:
for job, words in rules: for job, words in rules:
if any(word.lower() in text.lower() for word in words): if any(word.lower() in text.lower() for word in words):
return job return job
return "" return _infer_job_from_standalone_line(text)
def infer_source(text: str, filename: str) -> str: def infer_source(text: str, filename: str) -> str:
......
from backend.app.services.resume_parser_core import infer_major, main, normalize, parse_resume from backend.app.services.resume_parser_core import (
infer_job,
infer_major,
main,
normalize,
parse_resume,
)
def test_parse_text_resume(tmp_path): def test_parse_text_resume(tmp_path):
...@@ -76,3 +82,30 @@ def test_major_explicit_field_wins(): ...@@ -76,3 +82,30 @@ def test_major_explicit_field_wins():
def test_major_course_names_not_picked_when_no_major(): def test_major_course_names_not_picked_when_no_major():
text = "教育经历\n2017.09—2021.07 甘肃农业大学\n主修课程:市场营销、人力资源管理" text = "教育经历\n2017.09—2021.07 甘肃农业大学\n主修课程:市场营销、人力资源管理"
assert infer_major(text) == "" assert infer_major(text) == ""
def test_job_title_from_standalone_line(tmp_path):
resume = tmp_path / "张晓燕.txt"
resume.write_text(
"张晓燕\n性别:女年龄:28\n电话:18734915261 邮箱:1822742034@qq.com\n销售支持专员\n教育经历\n"
"2017.09—2021.07 甘肃农业大学\n农林经济管理\n主修课程:市场营销、管理学原理、人力资源管理",
encoding="utf-8",
)
parsed = parse_resume(resume)
assert parsed["jobTitle"] == "销售支持专员"
assert parsed["major"] == "农林经济管理"
def test_job_title_explicit_field_wins():
text = "个人简历\n应聘岗位:销售支持专员\n教育经历\n2017.09—2021.07 甘肃农业大学\n农林经济管理"
assert infer_job(text) == "销售支持专员"
def test_job_title_keyword_rule_still_works():
text = "负责前端架构,熟悉 React、Node 与工程化建设。"
assert infer_job(text) == "高级前端工程师"
def test_job_title_ignores_name_degree_and_motto_lines():
text = "张晓燕\n本科\n细心从每一个小细节开始。\n教育经历\n2017.09—2021.07 甘肃农业大学\n农林经济管理"
assert infer_job(text) == ""
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment