如何用Python nltk正则分词器实现英文分词同时去除冗余标点
NLTK RegExp分词器缩写去点高效解决方案
核心实现思路
不需要二次遍历全文,仅对正则匹配到的分词结果做轻量处理即可,处理的对象只有匹配到的有效token,数量远低于全文总字符数,性能远高于全文二次扫描,同时支持自定义规则扩展。
方案1:自定义分词器(最高效、扩展性最强)
直接继承NLTK的RegexpTokenizer类,重写tokenize方法,在返回结果前批量移除缩写中的点符号,你原有正则规则可以完全复用,不需要修改匹配逻辑。
代码实现
from nltk.tokenize import RegexpTokenizer class AbbrCleanTokenizer(RegexpTokenizer): def tokenize(self, text): # 仅遍历匹配到的token,无需扫描全文 return [ # 仅移除纯字母缩写的点,如需保留数字小数点可替换为下方注释行的逻辑 # token.replace('.', '') if not token.replace('.', '', 1).isdigit() else token token.replace('.', '') for token in super().tokenize(text) ] # 沿用你原来的正则规则,保证u.s.a等缩写不会被拆分 tokenizer = AbbrCleanTokenizer(r'[\w\.]+', gaps=False)
测试示例
test_text = "The u.s.a is a developed country. The latest GDP growth rate is 2.4%." print(tokenizer.tokenize(test_text))
开启小数点保留逻辑的输出结果:
['The', 'usa', 'is', 'a', 'developed', 'country', 'The', 'latest', 'GDP', 'growth', 'rate', 'is', '2.4']
方案2:轻量实现(无需自定义类)
如果不需要太复杂的扩展,也可以直接调用原有RegexpTokenizer后处理结果,逻辑和自定义类一致,性能无差异:
from nltk.tokenize import RegexpTokenizer tokenizer = RegexpTokenizer(r'[\w\.]+', gaps=False) test_text = "I come from the u.k." tokens = [t.replace('.', '') for t in tokenizer.tokenize(test_text)] print(tokens) # 输出:['I', 'come', 'from', 'the', 'uk']
效率说明
两种方案都只会处理匹配到的分词结果,不需要二次遍历全文,分词结果的数量通常仅为全文总字符数的10%~20%,运行效率远高于全文二次扫描,后续如果需要处理其他符号(比如单引号、连字符等),只需要修改替换逻辑即可,可扩展性满足要求。
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

