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

如何使用spaCy对含TEI类XML标签的命名实体文本分词?

处理带TEI风格XML标签的spaCy分词问题

嘿,我懂你现在的困扰——直接把带<personName>这类标签的文本丢给spaCy,肯定会把标签拆成奇怪的零散token(比如<、personName、>),既打乱了正常分词逻辑,又浪费了原有的实体标注信息。下面给你一套实用的解决方案,一步步来搞定:

核心思路

先把XML标签和实际文本内容分离:提取出所有带标签的实体信息,生成纯文本让spaCy处理,之后再把原有的实体标注映射回spaCy的处理结果里。这样既保证分词、词性标注等操作正常,又能完整保留原有的实体标签信息。

完整代码示例

import spacy
import re
from spacy.tokens import Span

# 加载spaCy英文模型(如果没装en_core_web_sm,先跑python -m spacy download en_core_web_sm)
nlp = spacy.load('en_core_web_sm')

# 你的带标签目标文本
txt = '<personName>Harry</personName> goes to <orgName>Hogwarts</orgName>. <personName>Sally</personName> lives in <locationName>London</locationName>.'

# 1. 提取实体信息和纯文本内容
# 正则匹配<xxxName>内容</xxxName>格式,确保前后标签一致
tag_pattern = re.compile(r'<(\w+)Name>(.*?)</\1Name>')

entities = []  # 存储(纯文本起始索引, 纯文本结束索引, 实体类型)
pure_text = ''
current_pos = 0

for match in tag_pattern.finditer(txt):
    # 把标签类型转成spaCy标准的大写格式(比如person→PERSON)
    ent_type = match.group(1).upper()
    # 获取标签包裹的实体内容
    ent_text = match.group(2)
    # 把标签前的普通文本追加到纯文本中,再加上实体内容
    pure_text += txt[current_pos:match.start()] + ent_text
    # 计算实体在纯文本中的起止位置
    ent_start = len(pure_text) - len(ent_text)
    ent_end = len(pure_text)
    entities.append((ent_start, ent_end, ent_type))
    # 更新当前处理位置到标签结束处
    current_pos = match.end()

# 追加文本最后一段无标签的内容
pure_text += txt[current_pos:]

# 2. 用spaCy处理纯文本
doc = nlp(pure_text)

# 3. 把原标签中的实体信息映射到spaCy的Doc对象中
# 保留spaCy自动识别的实体(不需要的话可以跳过这行)
existing_ents = list(doc.ents)
new_ents = []

for start, end, ent_type in entities:
    # 创建spaCy的Span对象,对应实体的位置和类型
    span = Span(doc, start, end, label=ent_type)
    new_ents.append(span)

# 合并并排序所有实体(按起始位置排序,避免重叠冲突)
all_ents = sorted(existing_ents + new_ents, key=lambda x: x.start)
doc.ents = all_ents

# 测试输出:查看分词结果
print("分词结果:")
for token in doc:
    print(f"{token.text:10} {token.pos_}")

# 测试输出:查看实体信息
print("\n实体信息:")
for ent in doc.ents:
    print(f"{ent.text:10} {ent.label_}")

代码说明

  • 正则提取:用正则精准匹配格式统一的TEI实体标签,确保提取的实体内容和类型一一对应。
  • 纯文本生成:剥离所有XML标签,让spaCy能基于纯自然语言完成正常的分词、词性标注等NLP操作。
  • 实体映射:把原标签中的实体信息转换成spaCy标准的Span对象,添加到doc.ents中,这样你既能利用spaCy的强大NLP功能,又能完整保留原有的实体标注。

如果你的文本存在嵌套标签,这个正则需要微调,但大部分TEI风格的实体标签都是非嵌套的,这个方案完全够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:20:42