1-1 获取词典和最大长度
# 规则分词
# 函数的输入就是词典的路径
def read_word_dict(dic_path):
    """
    加载词典,获取词典最长词的长度
    :param dic_path: 词典的路径
    :return dictionary,maxlength: 返回词典 和 词典的最大长度
    """
    # 词典以集合的形式进行存储,用集合的目的是去重
    dictionary = set()
    maxlength = 0       # 词典中最长词的长度
    # 读取词典
    # with open 读取词典
    with open(dic_path,'r',encoding = 'utf-8') as f:
        # 按行读取,readlines 获取的结果是带有换行符的,所以使用 line.strip 去掉空白,这里一行就是一个词
        for line in f.readlines():
            line = line.strip()
            dictionary.add(line)      # 将词放到词典里,词典里的内容就是一个 txt 文件
            line_length = len(line)   # 查看当前词的长度
            if line_length > maxlength:
                maxlength = line_length
    return dictionary,maxlength

# 调用函数,传入相对路径
dictionary,maxlength = read_word_dict('./data/dict.txt')
print(maxlength)
print(dictionary)
-->
4
{'长江', '长江大桥', '南京市', '大桥', '江', '南京市长'}
# 因为是一个集合,会默认哈希乱序,所以顺序会变
部分代码解释说明:
1-1-1
import os
print(os.path.abspath('.'))     # 查看当前路径的绝对路径
print(os.listdir('./data'))     # 查看当前路径下 data 文件夹中的内容

1-1-2
# 关于 readline 和 readlines 的用法
# 参考链接:https://blog.51cto.com/u_15149862/2791987 (2-5)

1-1-3
# with open的使用方式
# 参考链接:https://blog.51cto.com/u_15149862/2799896

1-1-4
# 集合 set() 的用法(这里的代码用到了 add) 
# 参考链接:https://blog.51cto.com/u_15149862/2800270 (3-1)
1-2 正向最大匹配法
def FMM_cut(dictionary,maxlength,text):
    """
    正向最大匹配法分词
    :param dictionary: 词典
    :param maxlength: 词最大长度
    :param text: 传入的语句
    :return: 分词结果
    """
    result = []     # 分词结果,用 result 列表接收;列表是按顺序返回的
    head = 0
    tail = len(text)
    # 最大正向匹配法,从左往右,依次匹配;相当于定义了一个头游标,和一个尾游标
    # 既然是从左往右走,所以是头一直在变,所以是循环条件 head < tail;头尾相等时结束,这句话就被分完了
    # 如果头小于尾
    while head < tail:
        # 最大长度是 maxlength,依次减一
        for size in range(maxlength,0,-1):
            if tail - head < size:
                continue
            piece = text[head:head+size]
            if piece in dictionary:
                word = piece
                result.append(word)
                head += size
                break
            if size == 1:
                piece = text[head:head+size]
                word = piece
                result.append(word)
                head += size
    return result

text = "南京市长江大桥"
text_cut = FMM_cut(dictionary,maxlength,text)
print(text_cut)
-->
['南京市长', '江', '大桥']
部分代码解释说明:
1-2-1
for i in range(4,0,-1):
    print(i)
-->
4
3
2
1
# 从 4 开始,到 0,每次 减 1
# 左开右闭,所以取到 1
1-3 逆向最大匹配法
def RMM_cut(dictionary,maxlength,text):
    """
    逆向最大匹配法分词
    :param dictionary: 词典
    :param maxlength: 词最大长度
    :param text:
    :return: 分词结果
    """
    result = []
    head = 0
    tail = len(text)
    # 如果头小于尾
    while head < tail:
        # 正向匹配中是从左向右,所以头一直在增加
        # 逆向匹配中是从右向左,所以是从尾一直减
        for size in range(maxlength, 0, -1):
            if tail - head < size:
                continue
            piece = text[tail-size:tail]
            if piece in dictionary:
                word = piece
                result.append(word)
                tail -= size
                break
            if size == 1:
                piece = text[tail-size:tail]
                word = piece
                result.append(word)
                tail -= size
    return result

text = "南京市长江大桥"
text_cut = RMM_cut(dictionary, maxlength, text)
print(text_cut[::-1])
-->
['南京市', '长江大桥']
部分代码解释说明:
1-3-1
In [67]: a = 'abcdefg'
In [68]: a[::-1]
Out[68]: 'gfedcba'
[::-1] 切片,取翻转,对当前列表进行反转;因为是逆向取出的,所以需要反转
1-4 双向最大匹配法
# 这是最好实现的,因为依赖于前面的两种方法
def BMM_cut(dictionary, maxlength, text):
    """
    双向最大匹配法分词
    :param dictionary: 词典
    :param maxlength: 词最大长度
    :param text:
    :return: 分词结果
    """
    fmm_txt_cut = FMM_cut(dictionary, maxlength, text)  # 正向最大匹配分词
    rmm_txt_cut = RMM_cut(dictionary, maxlength, text)  # 逆向最大匹配分词
    # 调用前两个方法,分别得到结果
    # 判断要结果短的
    if len(fmm_txt_cut) < len(rmm_txt_cut):     # 词数切分最少的作为结果
        return fmm_txt_cut
    else:
        return rmm_txt_cut[::-1]

text = "南京市长江大桥"
text_cut = BMM_cut(dictionary, maxlength, text)
print(text_cut)
-->
['南京市', '长江大桥']
# 以上是匹配法的三种方法
# 根据不同的评价方法,结果也会不同;比如词频等
知识点说明:
1. 什么是规则分词?
规则分词是一种中文分词技术,规则分词的方法有 3 种
分别是 正向最大匹配法、逆向最大匹配法 和 双向最大匹配法
2. 什么是正向最大匹配法?
> 正向最大匹配法做法:
   > 从左向右取待切分汉语句的m个字符作为匹配字段, m为词典中最长的词字符串长度
   > 查找词典并进行匹配,如果匹配成功:则将这个匹配字段作为一个词切分,如果匹配不成功:则将这个匹配字段的最后一个字去掉,剩下的作为匹配字段,进行再次匹配。直到切分出所有词。
3. 逆向最大匹配法是什么?
> 逆向最大匹配法做法:
   > 从右向左取待切分汉语句的m个字符作为匹配字段,m为词典中最长的词字符串长度。
   > 查找词典并进行匹配,如果匹配成功:则将这个匹配字段作为一个词切分,如果匹配不成功:则将这个匹配字段的最前面一个字去掉,剩下的作为匹配字段,进行再次匹配。直到切分出所有词。
   > 由于汉语中偏正结构较多,若从后向前匹配,可以适当提高精度。(偏正结构,就是 一句话中的核心词在后面,而前面的词是修饰后面的)
4. 什么是双向最大匹配法?
规则分词:双向最大匹配法
> 双向最大匹配法做法:
   > 将正向最大匹配法与逆向最大匹配法组合。先根据标点对文档进行粗切分,把文档分解成若干个句子,然后再对这些句子用正向最大匹配法和逆向最大匹配法进行扫描切分。如果两种分词方法得到的匹配结果相同,则认为分词正确,否则,按最小集处理。
(按最小集,就是词数最少,每个词比较长的划分,因为一般长词比较合理)
注:
规则分词匹配法,有着很明显的优点和缺点
优点:简单易懂、速度较快;
缺点:词典维护困难,无法解决歧义和未登录词问题;不好纠错,如果有错字也无法解决;
市面上的主流工具不会单独使用规则分词方法