如何去除nltk.word_tokenize输出中的转义字符?
如何去除nltk.word_tokenize输出中的转义字符?
你猜的方向没错——Python2到3的编码差异确实是诱因之一,但核心问题是你获取的原始文本里包含了控制字符(比如字节顺序标记BOM),这些字符在Python3的严格字符串体系中会以转义序列的形式保留,最终被nltk的分词器当成了token的一部分。
问题根源拆解
你的代码已经完成了字节到字符串的转换,但Gutenberg的这个文本文件开头可能带有非打印的BOM标记(或者其他控制字符)。在Python2中,字符串默认是字节流,这类字符可能被自动忽略或隐式处理;但Python3严格区分字节和Unicode字符串,这些不可见字符会被完整保留,分词时就会和后面的文本被打包成同一个token,出现你看到的转义序列。
解决方案:预处理清理文本
推荐你在分词前对原始字符串做预处理,过滤掉所有非打印控制字符,同时处理可能存在的BOM,具体步骤如下:
- 修改你的代码,在解码后添加预处理逻辑:
from __future__ import division import nltk, re, pprint from urllib.request import urlopen url = "https://www.gutenberg.org/cache/epub/75394/pg75394.txt" raw = urlopen(url).read() # 用utf-8-sig自动处理UTF-8 BOM标记,避免混入字符串 raw = raw.decode('utf-8-sig') # 过滤所有非打印控制字符(保留空格、标点、字母数字等可打印内容) raw = re.sub(r'[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u2029]', '', raw) # 再进行分词 tokens = nltk.word_tokenize(raw) print(type(tokens)) print(len(tokens)) print(tokens[:10])
- 代码说明:
utf-8-sig编码会自动识别并去除UTF-8文件开头的BOM标记(\ufeff),从解码环节就避免异常字符混入。- 正则表达式
r'[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u2029]'匹配所有ASCII和Unicode中的控制字符,用空字符串替换后就能彻底清理非打印内容。
备选方案:自动检测文件编码
如果上面的方法还没解决问题,可能是你用了错误的编码解码文件。可以用chardet库自动检测文件编码:
from __future__ import division import nltk, re, pprint, chardet from urllib.request import urlopen url = "https://www.gutenberg.org/cache/epub/75394/pg75394.txt" raw_bytes = urlopen(url).read() # 自动检测文件编码 encoding = chardet.detect(raw_bytes)['encoding'] raw = raw_bytes.decode(encoding) # 后续清理和分词步骤同上 raw = re.sub(r'[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u2029]', '', raw) tokens = nltk.word_tokenize(raw)
先安装chardet:pip install chardet,这样能确保用正确的编码解码字节流,从源头避免转义字符的产生。
修改后再运行代码,你的分词结果就会像书中示例一样,只包含单词和标点了。
备注:内容来源于stack exchange,提问作者green_ruby
相关产品推荐
相关产品推荐

