fix: md行跳过改为单行模式,移除块延续避免误杀用户消息

This commit is contained in:
youpaishidifu
2026-08-09 01:50:13 +08:00
parent d54fbe493f
commit cf59ff4c4d
+91 -2
View File
@@ -3028,8 +3028,16 @@ class MessageMonitor:
ocr_lines = []
for l in raw_text.split('\n'):
l = re.sub(r'\s*(?:[A-Za-z0-9]~)+\s*$', '', l).strip()
if l:
ocr_lines.append(l)
if not l:
continue
# ⭐ Task #1475: 单行 Markdown 跳过。
# 正常用户从不手动打 markdown(# 标题、|表格|、**加粗** 等)。
# 撞上 md 段落标记 → 跳过该行;没有 md 标记 → 正常收集。
# 不做"块延续",下一行立即恢复,避免误杀紧随其后的用户消息。
if self._is_markdown_line(l):
logger.debug(f"[{platform}] OCR: 跳过Markdown行: {l[:60]!r}")
continue
ocr_lines.append(l)
# —— 连续行合并(修复 EasyOCR 逗号断行) ——
# EasyOCR 对长消息在中文逗号","处拆行,导致前半句无时间戳被丢弃。
@@ -4788,6 +4796,87 @@ class MessageMonitor:
return True
return False
@staticmethod
def _is_markdown_line(line: str) -> bool:
"""⭐ Task #1475: 检测单行是否为 Markdown 强特征行。
正常用户从不手动打 markdown。一旦某一行 OCR 文本命中以下强特征,
即判定为 markdown 行,整行跳过,避免污染普通消息:
- # 标题(## 文档 / ##直接跟汉字 / ###1. 数字标题)
- | 表格行(首尾 | 或含 3+ 个 |)
- **加粗** / 裸 ** / 反引号 ` 代码
- <br> HTML 换行 / [text](url) 链接 / > 引用块
- --- 或 === 水平分隔线
- 编号列表 1. 2) 3、 (bot md 回复常见,用户日常不打)
注意:群名片 [专业皮肤定制] 不含 ] 后的 ( ,不会误判为链接;
纯 [xxx] 也不命中任何强特征,安全保留。
"""
if not line:
return False
s = line.strip()
# # 标题(含空格/直接跟汉字/数字/内联#)
if re.match(r'^#{1,6}(\s|\[|#|\u4e00-\u9fff|\d)', s):
return True
# | 表格行
if re.match(r'^\|.+\|$', s) or s.count('|') >= 3:
return True
# **加粗** 或裸 ** 或反引号代码
if '**' in s or '`' in s:
return True
# <br> HTML 换行标记
if re.search(r'<\s*br\s*/?\s*>', s, re.IGNORECASE):
return True
# [text](url) 链接(群名片 [xxx] 后无 ( 不命中)
if re.search(r'\[.+?\]\(', s):
return True
# > 引用块
if re.match(r'^>\s', s):
return True
# --- 或 === 水平分隔线
if re.match(r'^[-=]{3,}\s*$', s):
return True
# 编号列表项(1. 2) 3、)
if re.match(r'^\d{1,3}[\.\)、]\s', s):
return True
return False
@staticmethod
def _is_md_continuation(line: str) -> bool:
"""⭐ Task #1475: 判断某行是否为 markdown 块被 OCR 拆出来的"内容延续行"。
当上一行是 markdown 特征行时,OCR 常把同一 md 块的内容拆成多行,
带 ## 的头部被识别为 md 并跳过,但尾部纯文本行(如"你就换/个问题。没事/这个不影响")
无 md 特征会逃逸。此函数识别这些延续行并跳过。
判定为"延续行"(返回 True)的条件:
- 无问号(?/?)、无 @、不以吗/呢/么结尾(非明显提问)
- 非群名片 [xxx] 开头(群名片代表新消息起点)
- 非时间戳开头
- 长度 < 20(短句,符合 md 内容碎片特征)
否则视为明显用户消息,返回 False 退出 md 块。
"""
if not line:
return True
s = line.strip()
# 明显用户消息特征 → 不是延续
if '?' in s or '?' in s:
return False
if '@' in s:
return False
if s.endswith(('吗', '呢', '?', '?', '么')):
return False
# 群名片 [xxx] 开头 → 新消息起点,退出 md 块
if re.match(r'^[\[【][^\]】]*[\]】]', s):
return False
# 时间戳开头 → 新消息起点
if re.match(r'^\d{1,2}[::]', s):
return False
# 较长陈述句(>=20字)可能为真实消息,退出 md 块
if len(s) >= 20:
return False
# 默认:短、无问号、无@、非群名片 → 视为 md 内容延续
return True
def _split_and_denoise_segments(self, raw_text: str, platform: str) -> str:
"""混合文本预分割 + 分段噪声隔离。