如何将含Unicode转义序列\u####的字符串转换为UTF-8字符串
我明白你折腾一早上的困扰了——从文件里读出来的是\u9078\u629e这种文本形式的Unicode转义序列,没法直接变成实际的中文“選択”。咱们一步步把这个问题理顺:
问题根源
当你用encoding='utf-8'读取文件时,\u9078是被当作普通字符串字符(也就是反斜杠、u、9、0、7、8这几个单独的字符)读入的,而不是Python字面量里那种会自动解析的Unicode转义。所以直接判断“選択”是否在字符串里会返回False——因为这时候的字符串里根本没有中文,只有转义字符的文本形式。
正确的处理方法
你需要显式地把这些文本形式的转义序列解析成实际的Unicode字符,这里有两种简单靠谱的实现方式:
方法1:用encode+decode组合处理
with open('sample.txt', encoding='utf-8') as f: for line in f: # 先把读取到的字符串编码成utf-8字节流,再用unicode_escape解码 processed_line = line.encode('utf-8').decode('unicode_escape') print(processed_line) # 会输出: choice = 選択 print("選択" in processed_line) # 现在返回True
方法2:使用codecs模块
import codecs with open('sample.txt', 'r', encoding='utf-8') as f: for line in f: # 直接用codecs的decode方法解析unicode转义 processed_line = codecs.decode(line, 'unicode_escape') print(processed_line)
为什么你之前的写法报错?
你参考的那句代码里,line.encode().decode('unicode-escape').encode("latin-1").decode('utf-8')有个关键错误:当你用unicode-escape解码后,已经得到了中文“選択”,这时候再用latin-1编码完全行不通——因为latin-1只能编码0-255范围内的字符,而中文的Unicode编码远超出这个范围,所以会抛出UnicodeEncodeError。这一步encode("latin-1")完全是多余的,直接去掉就能正常工作了。
额外验证
你在IPython里输入"choice = \u9078\u629e"能得到带中文的字符串,是因为IPython会自动解析字符串字面量里的Unicode转义;但从文件读取的是原始文本,所以必须手动触发这个解析过程,上面的两种方法就是干这个的。
内容的提问来源于stack exchange,提问作者Rahul

