修复OCR md碎片漏网:短列表项/- 玩家义务/漏过、尾部#草残留
- _is_markdown_document: 行首列表项(- /*)、checkbox([V])、 md链接缺括号([text]( )检查移到len<10之前,短碎片不漏 - 时间戳分割else分支: 新增尾部#标题清理(\s+#[\u4e00-\u9fff]...$) - 提取后重检: extraction出的文本再走_is_markdown_document, 纯md碎片丢弃 - 过滤循环兜底: line进入texts.append前再扫一次尾部#标题+
This commit is contained in:
+40
-11
@@ -1149,13 +1149,20 @@ class MessageMonitor:
|
|||||||
extracted = self._extract_user_text_from_md_fragment(buf.strip())
|
extracted = self._extract_user_text_from_md_fragment(buf.strip())
|
||||||
for e in extracted:
|
for e in extracted:
|
||||||
if e:
|
if e:
|
||||||
|
# 再检:提取后的文本不应是纯 md 语法
|
||||||
|
if self._is_markdown_document(e):
|
||||||
|
logger.debug(f"[ocr] stage[{i}] md-only after extraction: {e[:60]!r}")
|
||||||
|
continue
|
||||||
expanded.append(e)
|
expanded.append(e)
|
||||||
if not extracted:
|
if not extracted:
|
||||||
logger.debug(f"[ocr] stage[{i}] markdown fragment skipped: {buf.strip()[:80]!r}")
|
logger.debug(f"[ocr] stage[{i}] markdown fragment skipped: {buf.strip()[:80]!r}")
|
||||||
else:
|
else:
|
||||||
msg = re.sub(r'\s*(?:[A-Za-z0-9]~)+\s*$', '', buf.strip())
|
msg = re.sub(r'\s*(?:[A-Za-z0-9]~)+\s*$', '', buf.strip())
|
||||||
if msg:
|
if msg:
|
||||||
expanded.append(msg)
|
# 清理末尾 #标题 碎片(如 "玩家义务? #草")
|
||||||
|
msg = re.sub(r'\s+#[\u4e00-\u9fff][^\s#\n]{0,30}$', '', msg).strip()
|
||||||
|
if msg:
|
||||||
|
expanded.append(msg)
|
||||||
buf = ''
|
buf = ''
|
||||||
else:
|
else:
|
||||||
buf += part
|
buf += part
|
||||||
@@ -1164,13 +1171,18 @@ class MessageMonitor:
|
|||||||
extracted = self._extract_user_text_from_md_fragment(buf.strip())
|
extracted = self._extract_user_text_from_md_fragment(buf.strip())
|
||||||
for e in extracted:
|
for e in extracted:
|
||||||
if e:
|
if e:
|
||||||
|
if self._is_markdown_document(e):
|
||||||
|
logger.debug(f"[ocr] stage[{i}] md-only after extraction: {e[:60]!r}")
|
||||||
|
continue
|
||||||
expanded.append(e)
|
expanded.append(e)
|
||||||
if not extracted:
|
if not extracted:
|
||||||
logger.debug(f"[ocr] stage[{i}] markdown fragment skipped: {buf.strip()[:80]!r}")
|
logger.debug(f"[ocr] stage[{i}] markdown fragment skipped: {buf.strip()[:80]!r}")
|
||||||
else:
|
else:
|
||||||
msg = re.sub(r'\s*(?:[A-Za-z0-9]~)+\s*$', '', buf.strip())
|
msg = re.sub(r'\s*(?:[A-Za-z0-9]~)+\s*$', '', buf.strip())
|
||||||
if msg:
|
if msg:
|
||||||
expanded.append(msg)
|
msg = re.sub(r'\s+#[\u4e00-\u9fff][^\s#\n]{0,30}$', '', msg).strip()
|
||||||
|
if msg:
|
||||||
|
expanded.append(msg)
|
||||||
|
|
||||||
# —— 逐行过滤 ——
|
# —— 逐行过滤 ——
|
||||||
ocr_lines = expanded
|
ocr_lines = expanded
|
||||||
@@ -1287,6 +1299,22 @@ class MessageMonitor:
|
|||||||
logger.debug(f"[{platform}] OCR 过滤: URL-only碎片 line={line!r}")
|
logger.debug(f"[{platform}] OCR 过滤: URL-only碎片 line={line!r}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# —— 末尾 #标题 碎片兜底 ——
|
||||||
|
# OCR 时间戳分割可能遗漏尾部 " #测试" " #草" 等 md 标题碎片
|
||||||
|
# 注:\s+ 要求空格在前,避免误杀 "C#语言" "中文#标签"
|
||||||
|
if re.search(r'#[\u4e00-\u9fff]', line):
|
||||||
|
cleaned = re.sub(r'\s+#[\u4e00-\u9fff][^\s#\n]{0,30}$', '', line).strip()
|
||||||
|
if cleaned != line:
|
||||||
|
if not cleaned or MessageMonitor._is_markdown_document(cleaned):
|
||||||
|
logger.debug(f"[{platform}] OCR 过滤: 末尾#标题碎片 line={line!r}")
|
||||||
|
continue
|
||||||
|
line = cleaned
|
||||||
|
# 如果 line 本身以 # 开头(纯 md),前面的 _is_markdown_document 应该已捕获
|
||||||
|
# 但此处再补一刀
|
||||||
|
if MessageMonitor._is_markdown_document(line):
|
||||||
|
logger.debug(f"[{platform}] OCR 过滤: md纯标题碎片 line={line!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
texts.append(line)
|
texts.append(line)
|
||||||
logger.debug(f"[{platform}] OCR -> {len(ocr_lines)} raw, {len(texts)} filtered, "
|
logger.debug(f"[{platform}] OCR -> {len(ocr_lines)} raw, {len(texts)} filtered, "
|
||||||
f"last=\"{texts[-1][:50] if texts else ''}\"")
|
f"last=\"{texts[-1][:50] if texts else ''}\"")
|
||||||
@@ -1641,11 +1669,21 @@ class MessageMonitor:
|
|||||||
# # 行首标题:短文本也检测(OCR 把 ##协议修 切成 5 字符片段)
|
# # 行首标题:短文本也检测(OCR 把 ##协议修 切成 5 字符片段)
|
||||||
if re.match(r'^#{1,6}(?:\s|\[|[\u4e00-\u9fff])', text):
|
if re.match(r'^#{1,6}(?:\s|\[|[\u4e00-\u9fff])', text):
|
||||||
return True
|
return True
|
||||||
|
# 行首列表项:短文本也检测(- 玩家义务 / * 注意)
|
||||||
|
# 必须放 len<10 之前,否则 "- 玩家应尊重他"(8c) 漏网
|
||||||
|
if re.match(r'^[\-\*]\s', text):
|
||||||
|
return True
|
||||||
# 全角括号退化 md 链接:短文本也检测
|
# 全角括号退化 md 链接:短文本也检测
|
||||||
if re.search(r'\](', text):
|
if re.search(r'\](', text):
|
||||||
return True
|
return True
|
||||||
if re.search(r'\[.+?\](', text):
|
if re.search(r'\[.+?\](', text):
|
||||||
return True
|
return True
|
||||||
|
# OCR 退化 md checkbox:短文本也检测([V] / [x])
|
||||||
|
if re.search(r'\[\s*[VXvx√✗]\s*\]', text):
|
||||||
|
return True
|
||||||
|
# OCR 退化 md 链接缺括号:短文本也检测
|
||||||
|
if re.search(r'\[.+?\]\(', text):
|
||||||
|
return True
|
||||||
if len(text) < 10:
|
if len(text) < 10:
|
||||||
return False
|
return False
|
||||||
# ##直接跟汉字(OCR 丢失 ##后空格时常见:##文档导航)
|
# ##直接跟汉字(OCR 丢失 ##后空格时常见:##文档导航)
|
||||||
@@ -1657,9 +1695,6 @@ class MessageMonitor:
|
|||||||
# 包含 .md 文件引用(如 "gin.md)" 分割后断开的链接)
|
# 包含 .md 文件引用(如 "gin.md)" 分割后断开的链接)
|
||||||
if re.search(r'\S+\.md\)', text):
|
if re.search(r'\S+\.md\)', text):
|
||||||
return True
|
return True
|
||||||
# 行首是 - 或 * 列表项(标准 md 列表)
|
|
||||||
if re.match(r'^[\-\*]\s', text):
|
|
||||||
return True
|
|
||||||
# 包含代码块标记 ``` 或 `code`
|
# 包含代码块标记 ``` 或 `code`
|
||||||
if re.search(r'`{1,3}', text):
|
if re.search(r'`{1,3}', text):
|
||||||
return True
|
return True
|
||||||
@@ -1670,12 +1705,6 @@ class MessageMonitor:
|
|||||||
# 内联 # # 标题标记(如 "# # 必装依赖" → 分割后 `# #` 或 `# #`)
|
# 内联 # # 标题标记(如 "# # 必装依赖" → 分割后 `# #` 或 `# #`)
|
||||||
if re.search(r'#\s*#', text):
|
if re.search(r'#\s*#', text):
|
||||||
return True
|
return True
|
||||||
# OCR 退化 md checkbox:`[V]`、`[v]`、`[x]` 等(含空格变体 [V ])
|
|
||||||
if re.search(r'\[\s*[VXvx√✗]\s*\]', text):
|
|
||||||
return True
|
|
||||||
# OCR 退化 md 链接:`[text](...` 缺闭合括号,QQ 群聊几乎不用此语法
|
|
||||||
if re.search(r'\[.+?\]\(', text):
|
|
||||||
return True
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
Reference in New Issue
Block a user