You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

匹配TSV文件ID的Markdown内容提取及TSV数据补全技术求助

问题描述

我有一个由CSV转换而来的TSV文件,以及一个存放Markdown文件的文件夹。需求是:遍历目录中的文件,打开文件名(如File_ID_1)与TSV文件ID列值匹配的Markdown文件,从中提取Animal和Fruit相关内容,分别补充到TSV文件的对应列中。

示例文件

TSV文件(example.tsv)内容:

ID   Data   Animal   Fruit
1   August
2   July
3   May
...   

目录Desktop/Files中的文件名:

File_ID_1
File_ID_2
File_ID_3
...

Markdown文件示例:

File_ID_1

**Animal**: Cat

**Fruit**: Peach

...

已完成代码

## Extracting relevant contents from a matched md file
import csv
import os
import re

df = 'example.tsv'
directory = 'Desktop/Files'

id_to_row = {}
with open(df, 'r', newline='', encoding='utf-8') as tsv_file:
    tsv_reader = csv.DictReader(tsv_file, delimiter='\t')
    for row_idx, row in enumerate(tsv_reader):
        id_to_row[int(row['ID'])] = row_idx

# Process markdown files
for filename in os.listdir(directory):
    if filename.endswith('.md'):
        id_match = re.match(r'File_ID_(\d+)\.md', filename)
        if id_match:
            file_id = int(id_match.group(1))
            markdown_path = os.path.join(directory, filename)
            
            with open(markdown_path, 'r', encoding='utf-8') as md_file:
                content = md_file.read()

同事建议用XPath表达式提取内容,但作为编程新手,不知道如何整合所有代码,需要帮助。


解决方案

针对当前的Markdown格式,用正则表达式比XPath更直接高效——XPath需要先把Markdown转成HTML,反而增加复杂度。下面是补全并优化后的完整代码:

import csv
import os
import re

# 配置文件路径
tsv_path = 'example.tsv'
md_directory = 'Desktop/Files'

# 1. 读取TSV所有数据,保存为列表方便后续修改,同时建立ID到行索引的映射
rows = []
id_to_index = {}
with open(tsv_path, 'r', newline='', encoding='utf-8') as tsv_file:
    reader = csv.DictReader(tsv_file, delimiter='\t')
    fieldnames = reader.fieldnames  # 保存表头
    for idx, row in enumerate(reader):
        row_id = int(row['ID'])
        rows.append(row)
        id_to_index[row_id] = idx

# 2. 定义正则表达式,匹配Animal和Fruit的内容(忽略大小写)
animal_pattern = re.compile(r'\*\*Animal\*\*:\s*(.+)', re.IGNORECASE)
fruit_pattern = re.compile(r'\*\*Fruit\*\*:\s*(.+)', re.IGNORECASE)

# 3. 遍历Markdown文件,提取内容并更新TSV数据
for filename in os.listdir(md_directory):
    if not filename.endswith('.md'):
        continue
    
    # 匹配文件名中的ID
    id_match = re.match(r'File_ID_(\d+)\.md', filename)
    if not id_match:
        continue
    
    file_id = int(id_match.group(1))
    # 检查该ID是否存在于TSV中
    if file_id not in id_to_index:
        print(f"ID {file_id} 未在TSV中找到,跳过文件 {filename}")
        continue
    
    # 读取Markdown文件内容
    md_path = os.path.join(md_directory, filename)
    with open(md_path, 'r', encoding='utf-8') as md_file:
        content = md_file.read()
    
    # 提取并填充Animal字段
    animal_match = animal_pattern.search(content)
    if animal_match:
        rows[id_to_index[file_id]]['Animal'] = animal_match.group(1).strip()
    
    # 提取并填充Fruit字段
    fruit_match = fruit_pattern.search(content)
    if fruit_match:
        rows[id_to_index[file_id]]['Fruit'] = fruit_match.group(1).strip()

# 4. 将更新后的数据写回TSV文件(建议先备份原文件)
with open(tsv_path, 'w', newline='', encoding='utf-8') as tsv_file:
    writer = csv.DictWriter(tsv_file, fieldnames=fieldnames, delimiter='\t')
    writer.writeheader()
    writer.writerows(rows)

print("TSV文件更新完成")

关键说明

  • 为什么不用XPath:XPath是XML/HTML解析工具,处理Markdown需先转成HTML(额外依赖markdown库),步骤繁琐。当前Markdown格式固定,正则完全能精准匹配。
  • 代码优化点:
    • 把TSV数据存在列表中,直接修改对应行字段,逻辑更直观。
    • 增加ID不存在的判断,避免报错。
    • 用re.IGNORECASE兼容大小写不同的写法(比如**animal**也能识别)。

如果坚持要用XPath,可参考以下简化实现(需额外安装markdown和lxml库):

# 先安装依赖:pip install markdown lxml
import markdown
from lxml import etree

# 读取Markdown内容后转成HTML
html_content = markdown.markdown(content)
tree = etree.HTML(html_content)

# 用XPath提取内容
animal = tree.xpath('//strong[text()="Animal"]/following-sibling::text()')
if animal:
    rows[id_to_index[file_id]]['Animal'] = animal[0].strip().replace(':', '').strip()

fruit = tree.xpath('//strong[text()="Fruit"]/following-sibling::text()')
if fruit:
    rows[id_to_index[file_id]]['Fruit'] = fruit[0].strip().replace(':', '').strip()

内容的提问来源于stack exchange,提问作者aoooooiiiiiiiiiiiiiii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:17:33