当前位置: 代码迷 >> 综合 >> jieba库:Tokenizer()类详解:(四)加载用户自定义词典
  详细解决方案

jieba库:Tokenizer()类详解:(四)加载用户自定义词典

热度:38   发布时间:2023-11-21 17:33:12.0

2021SC@SDUSC


源码:

def load_userdict(self, f):'''Load personalized dict to improve detect rate.Parameter:- f : A plain text file contains words and their ocurrences.Can be a file-like object, or the path of the dictionary file,whose encoding must be utf-8.Structure of dict file:word1 freq1 word_type1word2 freq2 word_type2...Word type may be ignored'''self.check_initialized()if isinstance(f, string_types):f_name = ff = open(f, 'rb')else:f_name = resolve_filename(f)
#===================================================================================for lineno, ln in enumerate(f, 1):line = ln.strip()if not isinstance(line, text_type):try:line = line.decode('utf-8').lstrip('\ufeff')except UnicodeDecodeError:raise ValueError('dictionary file %s must be utf-8' % f_name)if not line:continue# match won't be None because there's at least one characterword, freq, tag = re_userdict.match(line).groups()if freq is not None:freq = freq.strip()if tag is not None:tag = tag.strip()self.add_word(word, freq, tag)

load_userdict()适用于用户需要添加大量自定义词汇的情况,

此时需要将词汇以 word freq word_type 的形式每行一个存储在文件中。

然后使用该方法读取文件

开始用于监测字典是否已经加载,该方法:

    def check_initialized(self):if not self.initialized:self.initialize()

首个if else语句用于判断传入实参的类型(只能是文件或者文件的url),如果是文件的url,使用open()函数打开文件;如果是文件,则使用reslove_file()函数进行处理,reslove_file源码:

def resolve_filename(f):try:return f.nameexcept AttributeError:return repr(f)

for 循环中,enumerate()用于遍历可迭代的对象, enumerate(sequence[,start = 0])可以遍历sequence ,获得返回值(index,subsequence),start 的值为下标开始的值。详情

获得下标和每一行的值后,进行左右删减(去掉空格)

如果 line 不是 str类型,使用 utf-8 编码且删除左侧的字符 '\ufeff',关于这个字符的问题,详情戳,大致意思为读取记事本文件转码utf-8输出时会在左侧出现一个字符 '\ufeff',所以需要删除。

如果在删除空格和非法字符后 line 为空,则跳过改行的处理(没有数据)

使用re表达式进行匹配,并且使用 .groups()方法返回匹配后的结果(每个括号为一个结果),re_userdict的值为:

re_userdict = re.compile('^(.+?)( [0-9]+)?( [a-z]+)?$', re.U)

^(.+?)表示匹配首个任意字符,( [0-9]+)? 表示匹配一个空格以及之后的一串数字(仅匹配一次),( [a-z]+)?表示匹配一个空格以及之后的一串小写字母(仅匹配一次)。但是在^(表示字符串首)和$(表示字符串尾)之间时,整个正则表达式表示匹配 (一串字符,空格+一串数字,空格+一串字符),如果后两者匹配失败,所有的值都算在前者。例如:

 如果1234564 和 fsfas 之间有个空格就匹配成功!

 re.U的使用则是为了把\w \W \s \S等这些元字符按照 Unicode 的标准来考虑。例如:

pattern = re.compile(ur"a\s+b", re.U)
m = pattern.findall(u"dsadadsada\u3000b") # 匹配成功

pattern = re.compile(ur"a\s+b")
m = pattern.findall(u"dsadadsada\u3000b") # 匹配失败

\u3000是中文下的unicode空格符,如果不加 re.U 只认 ascii 中的空白符。

最后对获得的结果中非空的结果去除两边的空格(strip())

使用add_word(word,freq,tag)将word添加到字典。

讲到这里,我们应该考虑,添加词的时候既然可以省略词频和词性,那么省略后他们变成什么了呢?

看到add_word()源码

        

  相关解决方案