Python 标记HTML文档

Python 标记HTML文档,python,html,nlp,spacy,Python,Html,Nlp,Spacy,我有一个HTML文档,我想使用spaCy标记它,同时将HTML标记保留为单个标记。 这是我的密码: import spacy from spacy.symbols import ORTH nlp = spacy.load('en', vectors=False, parser=False, entity=False) nlp.tokenizer.add_special_case(u'<i>', [{ORTH: u'<i>'}]) nlp.tokenizer.add_sp

我有一个HTML文档,我想使用spaCy标记它,同时将HTML标记保留为单个标记。 这是我的密码:

import spacy
from spacy.symbols import ORTH
nlp = spacy.load('en', vectors=False, parser=False, entity=False)

nlp.tokenizer.add_special_case(u'<i>', [{ORTH: u'<i>'}])
nlp.tokenizer.add_special_case(u'</i>', [{ORTH: u'</i>'}])

doc = nlp('Hello, <i>world</i> !')

print([e.text for e in doc])
导入空间
从空间符号导入
nlp=spacy.load('en',vectors=False,parser=False,entity=False)
nlp.tokenizer.add_特殊_情况(u“”,[{ORTH:u'}])
nlp.tokenizer.add_特殊_情况(u“”,[{ORTH:u'}])
doc=nlp('你好,世界!')
打印([e.文档中e的文本])
输出为:

['Hello', ',', '<', 'i', '>', 'world</i', '>', '!']
['Hello'、'、'、'world'、'!']
如果我在标记周围加上空格,如下所示:

doc = nlp('Hello, <i> world </i> !')
doc=nlp('Hello,world!')
输出符合我的要求:

['Hello', ',', '<i>', 'world', '</i>', '!']
[“你好”,“世界”,“世界”!]
但我希望避免对HTML进行复杂的预处理


你知道我该怎么做吗?

你需要创建一个自定义标记器

您的自定义标记器将与spaCy的标记器完全相同,但它将从前缀和后缀中删除“”符号,并且将添加一个新前缀和一个新后缀规则

代码:

导入空间
从spacy.tokens导入令牌
Token.set_扩展名('tag',默认值=False)
def创建自定义标记器(nlp):
从spacy导入util
从spacy.tokenizer导入标记器
从spacy.lang.tokenizer\u异常导入令牌\u匹配
前缀=nlp.Defaults.prefixes+('^',)
后缀=nlp.Defaults.suffix+(“$”,)
#从前缀和后缀中删除标记符号
前缀=列表(前缀)
前缀。删除(“”)
后缀=元组(后缀)
中缀=nlp.Defaults.infixes
规则=nlp.Defaults.tokenizer\u异常
令牌匹配=令牌匹配
prefix\u search=(util.compile\u prefix\u regex(prefixes.search)
suffix_search=(util.compile_suffix_regex(后缀).search)
中缀_finditer=(util.compile_infix_regex(中缀).finditer)
返回标记器(nlp.vocab,rules=rules,
前缀搜索=前缀搜索,
后缀搜索=后缀搜索,
中缀查找器=中缀查找器,
令牌匹配=令牌匹配)
nlp=spacy.load('en\u core\u web\u sm')
标记器=创建自定义标记器(nlp)
nlp.tokenizer=标记器
doc=nlp('你好,世界!')
打印([e.文档中e的文本])

根据记录,这可能会变得更简单:使用当前版本的Spacy,您不必再创建自定义标记器。这就足够了。扩展中缀(以确保标记与单词分开),以及2。将标记添加为特殊情况:

import spacy
from spacy.symbols import ORTH

nlp = spacy.load("en_core_web_trf")

text = """Hello, <i>world</i> !"""
infixes = nlp.Defaults.infixes + [r'(<)']
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer
nlp.tokenizer.add_special_case(f"<i>", [{ORTH: f"<i>"}])    
nlp.tokenizer.add_special_case(f"</i>", [{ORTH: f"</i>"}])    

doc = nlp(text)
print([e.text for e in doc])
导入空间
从空间符号导入
nlp=spacy.load(“en_core\u web\u trf”)
text=“”你好,世界!”“

中缀=nlp.Defaults.infixes+[r'(很抱歉问这个问题,但是这个问题的目的是什么?为什么需要这样做?这是我正在培训的NER模型的数据。我想保留像I和b这样的标记作为模型的功能。您是否检查了-?您为什么不使用现有的HTML解析器,就像我需要标记文档一样,这样HTML解析器本身就不够了。遵循这一点首先,我可以考虑使用解析器用特殊的标记替换标记,然后标记化。这就是你的意思吗?
import spacy
from spacy.symbols import ORTH

nlp = spacy.load("en_core_web_trf")

text = """Hello, <i>world</i> !"""
infixes = nlp.Defaults.infixes + [r'(<)']
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer
nlp.tokenizer.add_special_case(f"<i>", [{ORTH: f"<i>"}])    
nlp.tokenizer.add_special_case(f"</i>", [{ORTH: f"</i>"}])    

doc = nlp(text)
print([e.text for e in doc])
['Hello', ',', '<i>', 'world', '</i>', '!']