瀏覽代碼

feat: improve markdown table normalization to retain original formatting and whitespace while accurately updating financial numbers in table cells

zhch158_admin 2 天之前
父節點
當前提交
d93ad54463
共有 1 個文件被更改,包括 67 次插入17 次删除
  1. 67 17
      zhch/utils/normalize_financial_numbers.py

+ 67 - 17
zhch/utils/normalize_financial_numbers.py

@@ -61,6 +61,8 @@ def normalize_markdown_table(markdown_content: str) -> str:
     """
     专门处理Markdown表格中的数字标准化
     
+    注意:保留原始markdown中的换行符,只替换表格内的文本内容
+    
     Args:
         markdown_content: Markdown内容
     
@@ -69,24 +71,72 @@ def normalize_markdown_table(markdown_content: str) -> str:
     """
     # 使用BeautifulSoup处理HTML表格
     from bs4 import BeautifulSoup, Tag
+    import re
+    
+    # 使用正则表达式找到所有表格的位置,并保留其前后的内容
+    # 匹配完整的HTML表格标签(包括嵌套)
+    table_pattern = r'(<table[^>]*>.*?</table>)'
+    
+    def normalize_table_match(match):
+        """处理单个表格匹配,保留原始格式"""
+        table_html = match.group(1)
+        original_table_html = table_html  # 保存原始HTML用于比较
+        
+        # 解析表格HTML
+        soup = BeautifulSoup(table_html, 'html.parser')
+        tables = soup.find_all('table')
+        
+        # 记录所有需要替换的文本(原始文本 -> 标准化文本)
+        replacements = []
+        
+        for table in tables:
+            if isinstance(table, Tag):
+                cells = table.find_all(['td', 'th'])
+                for cell in cells:
+                    if isinstance(cell, Tag):
+                        # 获取单元格的纯文本内容
+                        original_text = cell.get_text()
+                        normalized_text = normalize_financial_numbers(original_text)
+                        
+                        # 如果内容发生了变化,记录替换
+                        if original_text != normalized_text:
+                            # 找到单元格中所有文本节点并替换
+                            from bs4.element import NavigableString
+                            for text_node in cell.find_all(string=True, recursive=True):
+                                if isinstance(text_node, NavigableString):
+                                    text_str = str(text_node)
+                                    if text_str.strip():
+                                        normalized = normalize_financial_numbers(text_str.strip())
+                                        if normalized != text_str.strip():
+                                            # 保留原始文本节点的前后空白
+                                            if text_str.strip() == text_str:
+                                                # 纯文本节点,直接替换
+                                                text_node.replace_with(normalized)
+                                            else:
+                                                # 有前后空白,需要保留
+                                                leading_ws = text_str[:len(text_str) - len(text_str.lstrip())]
+                                                trailing_ws = text_str[len(text_str.rstrip()):]
+                                                text_node.replace_with(leading_ws + normalized + trailing_ws)
+        
+        # 获取修改后的HTML
+        modified_html = str(soup)
+        
+        # 如果内容没有变化,返回原始HTML(保持原始格式)
+        # 检查是否只是格式变化(换行、空格等)
+        original_text_only = re.sub(r'\s+', '', original_table_html)
+        modified_text_only = re.sub(r'\s+', '', modified_html)
+        
+        if original_text_only == modified_text_only:
+            # 只有格式变化,返回原始HTML以保留换行符
+            return original_table_html
+        
+        # 有实际内容变化,返回修改后的HTML
+        return modified_html
+    
+    # 使用正则替换,只替换表格内容,保留其他部分(包括换行符)不变
+    normalized_content = re.sub(table_pattern, normalize_table_match, markdown_content, flags=re.DOTALL)
     
-    soup = BeautifulSoup(markdown_content, 'html.parser')
-    tables = soup.find_all('table')
-    
-    for table in tables:
-        if isinstance(table, Tag):
-            cells = table.find_all(['td', 'th'])
-            for cell in cells:
-                if isinstance(cell, Tag):
-                    original_text = cell.get_text()
-                    normalized_text = normalize_financial_numbers(original_text)
-                    
-                    # 如果内容发生了变化,更新单元格内容
-                    if original_text != normalized_text:
-                        cell.string = normalized_text
-    
-    # 返回更新后的HTML
-    return str(soup)
+    return normalized_content
 
 def normalize_json_table(json_content: str) -> str:
     """