如何阅读中文文件?

时间:2016-04-07 20:51:27

标签: python unicode utf-8 chinese-locale

我坚持使用所有这些令人困惑的编码内容。我有一个包含中文潜艇的文件。我实际上相信它是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都包含完整的中文文本。为什么我不能循环呢?

请帮我理解这一点。这对我来说非常混乱,文档让我无处可去。谷歌只是让我遇到了有人解决的类似问题,但到目前为止还没有任何解释让我理解这一点。

2 个答案:

答案 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: