fix: 科目名称补位 + 摘要过滤科目名称
- 科目代码没名称时,从下方200px内补取含中文的文本作为名称 - 摘要候选排除以-/-开头的会计科目文本 - 摘要候选排除与代码名称重复的候选 - 名称补位排除含其他科目代码的行(防误匹配)
This commit is contained in:
parent
da0b5ff0b8
commit
5f3df306c2
|
|
@ -178,6 +178,41 @@ class K3VoucherParser:
|
|||
if not codes:
|
||||
return self._parse_entries_fallback()
|
||||
|
||||
# === 4.3 科目名称补位:如果代码没有名称,从附近行找 ===
|
||||
for code in codes:
|
||||
if code['name']: # 已有名称则跳过
|
||||
continue
|
||||
# 在当前代码下方附近找包含中文的文本(排除含其他科目代码的行)
|
||||
name_candidates = []
|
||||
for text, conf, cx, cy, box in self.lines:
|
||||
if conf < 0.5:
|
||||
continue
|
||||
if not re.search(r'[\u4e00-\u9fff]', text): # 必须含中文字
|
||||
continue
|
||||
if any(k in text for k in skip_keywords + ['合计', '亿', '千', '百', '拾', '万']):
|
||||
continue
|
||||
if re.match(r'^[\d.\-,]+$', text.strip()):
|
||||
continue
|
||||
if len(text.strip()) < 3:
|
||||
continue
|
||||
if cx < 400 or cx > 1300: # 名称列通常在x=400-1300
|
||||
continue
|
||||
if re.search(r'(公司|有限|集团|企业)', text): # 排除公司名
|
||||
continue
|
||||
if text.strip() in ('未到账', '已到账', '未达', '已达'):
|
||||
continue
|
||||
# 排除包含其他科目代码的行(如 "6603.02-财务费用")
|
||||
if re.search(r'\d{3,}\.\d', text):
|
||||
continue
|
||||
dist_y = cy - code['y_pos']
|
||||
if 0 < dist_y < 200: # 代码下方200px以内
|
||||
name_candidates.append((text, dist_y, cx, cy))
|
||||
if name_candidates:
|
||||
# 取y距离最近的
|
||||
name_candidates.sort(key=lambda x: (x[1], -x[2]))
|
||||
code['name'] = name_candidates[0][0]
|
||||
code['y_pos'] = max(code['y_pos'], name_candidates[0][3]) # 更新y为名称位置
|
||||
|
||||
# === 4.5 摘要提取:从剩余 OCR 文字中找摘要 ===
|
||||
code_y_min = min(c['y_pos'] for c in codes)
|
||||
|
||||
|
|
@ -218,6 +253,13 @@ class K3VoucherParser:
|
|||
continue
|
||||
if text.strip() in ('未到账', '已到账', '未达', '已达'):
|
||||
continue
|
||||
# 过滤垃圾摘要:纯字母数字/太短/无中文
|
||||
if not re.search(r'[\u4e00-\u9fff]', text): # 没有中文字,排除
|
||||
continue
|
||||
if len(text.strip()) < 4: # 太短
|
||||
continue
|
||||
if conf < 0.6: # 提高置信度要求
|
||||
continue
|
||||
# 过滤非摘要的日期/期号文本
|
||||
if re.match(r'\d{3}年第\d+期', text.strip()):
|
||||
continue
|
||||
|
|
@ -233,6 +275,23 @@ class K3VoucherParser:
|
|||
# 过滤包含"公司"、"物业"、"有限"等公司相关词
|
||||
if re.search(r'(公司|有限|物业|集团|企业)', text):
|
||||
continue
|
||||
# 过滤科目名称文本:以 -/- 开头的会计科目
|
||||
if re.match(r'^[--][^\d]', text.strip()) and any(
|
||||
kw in text for kw in ['银行', '货币', '账款', '费用', '收入', '成本',
|
||||
'应收', '应付', '预付', '预收', '其他', '库存',
|
||||
'管理', '财务', '手续费', '押金', '资本']
|
||||
):
|
||||
continue
|
||||
# 过滤纯科目名称(在代码附近找到的科目名不应作为摘要)
|
||||
if len(text.strip()) < 20: # 短文本更容易是科目名
|
||||
is_near_name = False
|
||||
for c in codes:
|
||||
if c['name'] and c['name'] in text:
|
||||
if abs(c['y_pos'] - cy) < 100:
|
||||
is_near_name = True
|
||||
break
|
||||
if is_near_name:
|
||||
continue
|
||||
if cy < desc_upper_bound:
|
||||
continue
|
||||
# 去重:跳过 y 距离 < 30 的重复文本
|
||||
|
|
|
|||
Loading…
Reference in New Issue