如何修改Spacy英文分词器实现单词内部多标点拆分
spaCy英文分词器新增连写标点拆分能力方案
核心逻辑
spaCy默认英文分词基于前缀、后缀、中缀、特殊例外四类规则实现,要保留全部原有规则、仅新增连写标点拆分能力,不需要重写分词器,只要在原有中缀规则集末尾追加自定义边界匹配规则即可——中缀规则负责识别两个字符之间的分词边界,新增规则不会干扰原有规则的执行优先级。
可直接运行的实现代码
import spacy from spacy.lang.char_classes import ALPHA from spacy.util import compile_infix_regex # 加载预训练模型 nlp = spacy.load("en_core_web_md") # 提取模型自带的全部默认中缀规则,不做任何删改 default_infixes = list(nlp.Defaults.infixes) # 新增自定义拆分规则:覆盖单词与连写标点、不同类连写标点的边界 # 规则1:字母/数字后紧跟.、(、)、,、!、?、;时,在两者间拆分 # 规则2:句尾类标点后紧跟字母/数字、(时,在两者间拆分 # 如需拆分更多标点,直接在方括号内追加对应字符即可 custom_split_rule = r"(?<=[{a}0-9])(?=[\.\(\),!?;])|(?<=[\.\),!?;])(?=[{a}0-9\(])".format(a=ALPHA) default_infixes.append(custom_split_rule) # 编译正则并替换分词器的中缀匹配逻辑 new_infix_re = compile_infix_regex(default_infixes) nlp.tokenizer.infix_finditer = new_infix_re.finditer # 验证测试用例 doc = nlp("running.(together") assert [t.text for t in doc] == ["running", ".", "(", "together"]
方案说明
- 原有分词逻辑100%保留:所有默认规则未做修改,仅追加了一条低优先级的补充规则,缩写识别、连字符处理、URL/特殊符号识别、分词例外表全部正常生效
- 规则可灵活扩展:如果需要拆分其他连写标点(比如引号、冒号),直接修改正则里的字符集即可
- 不要直接替换
nlp.tokenizer实例,否则会丢失模型内置的特殊token匹配、实体关联的分词配置
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

