我坚持使用所有这些令人困惑的编码内容。我有一个包含中文潜艇的文件。我实际上相信它是UTF-8,因为在Notepad ++中使用它给了我一个非常好的结果。如果我设置gb2312,中文部分仍然没问题,但我会看到一些UTF8代码没有被转换。
目标是遍历文件中的文本并计算不同字符出现的次数。
import os
import re
import io
character_dict = {}
for dirname, dirnames, filenames in os.walk('.'):
for filename in filenames:
if "srt" in filename:
import codecs
f = codecs.open(filename, 'r', 'gb2312', errors='ignore')
s = f.read()
# deleting {}
s = re.sub('{[^}]+}', '', s)
# deleting every line that does not start with a chinese char
s = re.sub(r'(?m)^[A-Z0-9a-z].*\n?', '', s)
# delete non chinese chars
s = re.sub(r'[\s\.A-Za-z0-9\?\!\\/\-\"\,\*]', '', s)
#print s
s = s.encode('gb2312')
print s
for c in s:
#print c
pass
这实际上会给我完整的中文文本。但是当我打印出底部的循环时,我只会得到问号,而不是单个字符。
另请注意我说它是UTF8,但我必须使用gb2312进行编码,并将其作为我的gnome-terminal中的设置。如果我在代码中将其设置为UTF8,那么无论我将终端设置为UTF8还是gb2312,我都会得到垃圾。所以也许这个文件毕竟不是UTF8!
在任何情况下,s都包含完整的中文文本。为什么我不能循环呢?
请帮我理解这一点。这对我来说非常混乱,文档让我无处可去。谷歌只是让我遇到了有人解决的类似问题,但到目前为止还没有任何解释让我理解这一点。
答案 0 :(得分:1)
gb2312
是一种多字节编码。如果迭代使用它编码的字节字符串,则将遍历字节,而不是遍历要计数(或打印)的字符。您可能希望在编码之前对unicode
字符串进行迭代。如有必要,您可以将各个代码点(字符)编码为它们自己的字节串以进行输出:
# don't do s = s.encode('gb2312')
for c in s: # iterate over the unicode codepoints
print c.encode('gb2312') # encode them individually for output, if necessary
答案 1 :(得分:0)
您正在打印个别字节。 GB2312是一个多字节编码,每个码点使用2个字节。单独打印这些字节不会产生有效输出,编号
解决方案是在打印时不从Unicode编码为字节。改为循环遍历Unicode字符串:
# deleting {}
s = re.sub('{[^}]+}', '', s)
# deleting every line that does not start with a chinese char
s = re.sub(r'(?m)^[A-Z0-9a-z].*\n?', '', s)
# delete non chinese chars
s = re.sub(r'[\s\.A-Za-z0-9\?\!\\/\-\"\,\*]', '', s)
#print s
# No `s.encode()`!
for char in s:
print char
你可以单独编码每个char
字符:
for char in s:
print char
但是如果你的控制台/ IDE /终端配置正确,你应该可以直接打印而不会出错,特别是因为你的print s.encode('gb2312
)`产生了正确的输出。
您似乎也将UTF-8(编码)与Unicode standard混淆。 UTF-8可用于表示以字节为单位的Unicode数据。 GB2312是一个编码 too ,可用于表示Unicode文本的(子集),以字节为单位。
您可能想要阅读Python和Unicode: