【jieba】添加带有空格或其他符号的词典不生效

457 阅读1分钟

jieba是我们最常用的分词包,其分词效率远高于其他基于神经网络的工具。

jieba带有词典功能,但对于一些特殊的词,配置进词典却不起作用......

问题

看下面这个例子,添加带有· 的词进分词词典,却不能正确分词。

jieba.__version__ = '0.42.1'
import jieba


jieba.add_word("鲁路修·兰佩路基")
res = jieba.lcut("鲁路修·兰佩路基")
print(res)
jieba.add_word("鲁路修 兰佩路基")
res = jieba.lcut("鲁路修 兰佩路基")
print(res)
['鲁路', '修', '·', '兰佩', '路基']
['鲁路', '修', ' ', '兰佩', '路基']

解决方案

添加两行代码即可

import jieba
import re


jieba.re_han_default = re.compile("([\u4E00-\u9FD5a-zA-Z0-9+#&\._%\-· ]+)", re.U)
jieba.add_word("鲁路修·兰佩路基")
res = jieba.lcut("鲁路修·兰佩路基")
print(res)
jieba.add_word("鲁路修 兰佩路基")
res = jieba.lcut("鲁路修 兰佩路基")
print(res)
['鲁路修·兰佩路基']
['鲁路修 兰佩路基']

原理

首先看一下jieba分词的逻辑,仅截取相关部分

re_han_default = re.compile("([\u4E00-\u9FD5a-zA-Z0-9+#&._%-]+)", re.U)
re_han = re_han_default
blocks = re_han.split(sentence)
for blk in blocks:
    if re_han.match(blk):
        for word in cut_block(blk):
            yield word

jieba首先将输入进行分块,分块的依据是re_han_default里定义的字符。可以看到,字符中不包含测试使用到的· ,所以在这步,输入的鲁路修·兰佩路基已经被切成['', '鲁路修', '·', '兰佩路基', ''],在接下来对每块进行分词中,并没有包含在词典中的词了,所以未能正确分词。 因此,为了避免包含· 的词被切分,将blocks划分的正则中添加这些字符,即可解决问题,如解决方案部分所呈现。