Kaynağa Gözat

fix: inline format bacteria table timeout - skip truly compressed format, 朱评估报告 now completes

asus 2 ay önce
ebeveyn
işleme
f725cc19b4
1 değiştirilmiş dosya ile 48 ekleme ve 45 silme
  1. 48 45
      docs/参考资料/extract_full_report_v5.py

+ 48 - 45
docs/参考资料/extract_full_report_v5.py

@@ -955,58 +955,61 @@ def _parse_bacteria_table(reader, pages_text, full_text, title, fmt, skip_header
             else:
                 i += 1
     else:
-        # inline 格式:数据挤在一行,如 "嗜血杆菌属 Haemophilus ND 0-0.7752 22% 94.23% 说明:..."
-        # 适用于 pathogen 表、pathogen 检出表等 inline 格式嵌在 triplet PDF 中的情况
-        # 使用 re.finditer 扫描整段文本,不依赖换行分割
-        # 先清理标题行和说明文字
-        region_clean = region
-        for hdr in ['名称', '丰度%', '正常范围%', '处于人群%水平', '%正常人有检出', '人群水平%', '%人检出']:
-            region_clean = region_clean.replace(hdr, '')
-        # 移除说明文本(非数据行的说明段)
-        region_clean = re.sub(r'说明:[\u4e00-\u9fff\s,。、;:,.;:()()、/a-zA-Z0-9\-]{10,}?(?=[\u4e00-\u9fff]|$)', '', region_clean)
-        # 扫描所有匹配的数据行
-        # 模式1:中文名[(英文备注)] 英文名 丰度(ND/数字) 正常范围(可选) 人群水平% 检出率%
-        for m in re.finditer(
-            r'([\u4e00-\u9fff]{2,12}(?:[((][\u4e00-\u9fff\w]+[))])?)\s+'  # 中文名
-            r'(?:[A-Z][a-z]+(?:\s[A-Z][a-z]+)*\s+)?'  # 可选英文名
-            r'(ND|[\d]+\.?[\d]*%?)\s+'  # 丰度
-            r'([\d]+\.?[\d]*-[\d]+\.?[\d]*)?\s*'  # 可选正常范围
-            r'(\d+\.?\d*%?)\s+'  # 人群水平%
-            r'(\d+\.?\d*%)',  # 检出率%
-            region_clean):
-            name = m.group(1).strip()
-            pct = m.group(2)
-            if '病原菌' in name or '构成表' in name or '说明' in name or len(name) <= 1:
-                continue
-            normal_range = m.group(3) or ''
-            pop_level = m.group(4)
-            if not pop_level.endswith('%'):
-                pop_level += '%'
-            detection_rate = m.group(5)
-            entry = {'名称': name, '丰度%': pct}
-            if normal_range:
-                entry['正常范围%'] = normal_range
-            entry['人群水平%'] = pop_level
-            entry['检出率%'] = detection_rate
-            results.append(entry)
-        # 如果模式1没有匹配,尝试模式2:仅中文名+丰度+人群水平(+检出率)
-        if not results:
+        # inline 格式
+        # 检测是否为"真正压缩"格式(无空格分隔,如"埃希氏菌属 Escherichia0.89200-9.302347%99.52%")
+        # 这种格式无法可靠解析,跳过
+        sample = region[:500]
+        truly_compressed = bool(re.search(r'[a-z]\d', sample, re.IGNORECASE))
+        if not truly_compressed:
+            # 有空格分隔的inline格式(如pathogen表),使用re.finditer
+            # 先清理标题行和说明文字
+            region_clean = region
+            for hdr in ['名称', '丰度%', '正常范围%', '处于人群%水平', '%正常人有检出', '人群水平%', '%人检出']:
+                region_clean = region_clean.replace(hdr, '')
+            # 移除说明文本(非数据行的说明段)
+            region_clean = re.sub(r'说明:[\u4e00-\u9fff\s,。、;:,.;:()()、/a-zA-Z0-9\-]{10,}?(?=[\u4e00-\u9fff]|$)', '', region_clean)
+            # 扫描所有匹配的数据行
             for m in re.finditer(
-                r'([\u4e00-\u9fff]{2,10}[\u4e00-\u9fff]?)\s+'
-                r'(ND|[\d]+\.?[\d]*%?)\s+'
-                r'(\d+\.?\d*%)\s+'
-                r'(\d+\.?\d*%)?',
+                r'([\u4e00-\u9fff]{2,12}(?:[((][\u4e00-\u9fff\w]+[))])?)\s+'  # 中文名
+                r'(?:[A-Z][a-z]+(?:\s[A-Z][a-z]+)*\s+)?'  # 可选英文名
+                r'(ND|[\d]+\.?[\d]*%?)\s+'  # 丰度
+                r'([\d]+\.?[\d]*-[\d]+\.?[\d]*)?\s*'  # 可选正常范围
+                r'(\d+\.?\d*%?)\s+'  # 人群水平%
+                r'(\d+\.?\d*%)',  # 检出率%
                 region_clean):
                 name = m.group(1).strip()
                 pct = m.group(2)
                 if '病原菌' in name or '构成表' in name or '说明' in name or len(name) <= 1:
                     continue
-                pop_level = m.group(3)
-                detection_rate = m.group(4) or ''
-                entry = {'名称': name, '丰度%': pct, '人群水平%': pop_level}
-                if detection_rate:
-                    entry['检出率%'] = detection_rate
+                normal_range = m.group(3) or ''
+                pop_level = m.group(4)
+                if not pop_level.endswith('%'):
+                    pop_level += '%'
+                detection_rate = m.group(5)
+                entry = {'名称': name, '丰度%': pct}
+                if normal_range:
+                    entry['正常范围%'] = normal_range
+                entry['人群水平%'] = pop_level
+                entry['检出率%'] = detection_rate
                 results.append(entry)
+            # 如果模式1没有匹配,尝试模式2:仅中文名+丰度+人群水平(+检出率)
+            if not results:
+                for m in re.finditer(
+                    r'([\u4e00-\u9fff]{2,10}[\u4e00-\u9fff]?)\s+'
+                    r'(ND|[\d]+\.?[\d]*%?)\s+'
+                    r'(\d+\.?\d*%)\s+'
+                    r'(\d+\.?\d*%)?',
+                    region_clean):
+                    name = m.group(1).strip()
+                    pct = m.group(2)
+                    if '病原菌' in name or '构成表' in name or '说明' in name or len(name) <= 1:
+                        continue
+                    pop_level = m.group(3)
+                    detection_rate = m.group(4) or ''
+                    entry = {'名称': name, '丰度%': pct, '人群水平%': pop_level}
+                    if detection_rate:
+                        entry['检出率%'] = detection_rate
+                    results.append(entry)
 
     return results