我必须编写一个支持读取文件的脚本,该文件可以保存为Unicode或Ansi(使用MS的记事本)。

我没有任何关于文件中编码格式的指示,我如何支持这两种编码格式? (一种在不知道高级格式的情况下读取文件的通用方法)。

===============>>#1 票数:12 已采纳

MS Notepad为用户提供了4种编码选择,用笨拙的混淆术语表示:

“Unicode”是UTF-16,写成little-endian。 “Unicode big endian”是UTF-16,写的是big-endian。 在两种UTF-16情况下,这意味着将写入适当的BOM。 使用utf-16解码这样的文件。

“UTF-8”是UTF-8; 记事本显式写入“UTF-8 BOM”。 使用utf-8-sig解码这样的文件。

“ANSI”令人震惊。 这是“无论此计算机上的默认遗留编码是什么”的MS术语。

以下是我所知道的Windows编码列表以及它们用于的语言/脚本:

cp874  Thai
cp932  Japanese 
cp936  Unified Chinese (P.R. China, Singapore)
cp949  Korean 
cp950  Traditional Chinese (Taiwan, Hong Kong, Macao(?))
cp1250 Central and Eastern Europe 
cp1251 Cyrillic ( Belarusian, Bulgarian, Macedonian, Russian, Serbian, Ukrainian)
cp1252 Western European languages
cp1253 Greek 
cp1254 Turkish 
cp1255 Hebrew 
cp1256 Arabic script
cp1257 Baltic languages 
cp1258 Vietnamese
cp???? languages/scripts of India  

如果文件是在正在读取它的计算机上创建的,则可以通过locale.getpreferredencoding()获取“ANSI”编码。 否则,如果您知道它来自何处,则可以指定在不是UTF-16时使用的编码。 失败了,猜猜。

小心使用codecs.open()来读取Windows上的文件。 文档说:“”注意文件总是以二进制模式打开,即使没有指定二进制模式。这样做是为了避免因使用8位值编码而导致数据丢失。这意味着不会自动转换'\\ n '完成了阅读和写作。“”这意味着你的线将以\\r\\n结束,你将需要/想要剥离它们。

把它们放在一起:

使用所有4种编码选项保存的示例文本文件在记事本中如下所示:

The quick brown fox jumped over the lazy dogs.
àáâãäå

这是一些演示代码:

import locale

def guess_notepad_encoding(filepath, default_ansi_encoding=None):
    with open(filepath, 'rb') as f:
        data = f.read(3)
    if data[:2] in ('\xff\xfe', '\xfe\xff'):
        return 'utf-16'
    if data == u''.encode('utf-8-sig'):
        return 'utf-8-sig'
    # presumably "ANSI"
    return default_ansi_encoding or locale.getpreferredencoding()

if __name__ == "__main__":
    import sys, glob, codecs
    defenc = sys.argv[1]
    for fpath in glob.glob(sys.argv[2]):
        print
        print (fpath, defenc)
        with open(fpath, 'rb') as f:
            print "raw:", repr(f.read())
        enc = guess_notepad_encoding(fpath, defenc)
        print "guessed encoding:", enc
        with codecs.open(fpath, 'r', enc) as f:
            for lino, line in enumerate(f, 1):
                print lino, repr(line)
                print lino, repr(line.rstrip('\r\n'))

这是使用命令\\python27\\python read_notepad.py "" t1-*.txt在Windows“命令提示符”窗口中运行时的输出

('t1-ansi.txt', '')
raw: 'The quick brown fox jumped over the lazy dogs.\r\n\xe0\xe1\xe2\xe3\xe4\xe5
\r\n'
guessed encoding: cp1252
1 u'The quick brown fox jumped over the lazy dogs.\r\n'
1 u'The quick brown fox jumped over the lazy dogs.'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5\r\n'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5'

('t1-u8.txt', '')
raw: '\xef\xbb\xbfThe quick brown fox jumped over the lazy dogs.\r\n\xc3\xa0\xc3
\xa1\xc3\xa2\xc3\xa3\xc3\xa4\xc3\xa5\r\n'
guessed encoding: utf-8-sig
1 u'The quick brown fox jumped over the lazy dogs.\r\n'
1 u'The quick brown fox jumped over the lazy dogs.'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5\r\n'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5'

('t1-uc.txt', '')
raw: '\xff\xfeT\x00h\x00e\x00 \x00q\x00u\x00i\x00c\x00k\x00 \x00b\x00r\x00o\x00w
\x00n\x00 \x00f\x00o\x00x\x00 \x00j\x00u\x00m\x00p\x00e\x00d\x00 \x00o\x00v\x00e
\x00r\x00 \x00t\x00h\x00e\x00 \x00l\x00a\x00z\x00y\x00 \x00d\x00o\x00g\x00s\x00.
\x00\r\x00\n\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\r\x00\n\x00'
guessed encoding: utf-16
1 u'The quick brown fox jumped over the lazy dogs.\r\n'
1 u'The quick brown fox jumped over the lazy dogs.'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5\r\n'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5'

('t1-ucb.txt', '')
raw: '\xfe\xff\x00T\x00h\x00e\x00 \x00q\x00u\x00i\x00c\x00k\x00 \x00b\x00r\x00o\
x00w\x00n\x00 \x00f\x00o\x00x\x00 \x00j\x00u\x00m\x00p\x00e\x00d\x00 \x00o\x00v\
x00e\x00r\x00 \x00t\x00h\x00e\x00 \x00l\x00a\x00z\x00y\x00 \x00d\x00o\x00g\x00s\
x00.\x00\r\x00\n\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\r\x00\n'
guessed encoding: utf-16
1 u'The quick brown fox jumped over the lazy dogs.\r\n'
1 u'The quick brown fox jumped over the lazy dogs.'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5\r\n'
2 u'\xe0\xe1\xe2\xe3\xe4\xe5'

需要注意的事项:

(1)“mbcs”是文件系统伪编码,它与解码文件内容完全没有关系。 在默认编码为cp1252的系统上,它就像latin1 (aarrgghh !!); 见下文

>>> all_bytes = "".join(map(chr, range(256)))
>>> u1 = all_bytes.decode('cp1252', 'replace')
>>> u2 = all_bytes.decode('mbcs', 'replace')
>>> u1 == u2
False
>>> [(i, u1[i], u2[i]) for i in xrange(256) if u1[i] != u2[i]]
[(129, u'\ufffd', u'\x81'), (141, u'\ufffd', u'\x8d'), (143, u'\ufffd', u'\x8f')
, (144, u'\ufffd', u'\x90'), (157, u'\ufffd', u'\x9d')]
>>>

(2) chardet非常擅长检测基于非拉丁文字(中文/日文/韩文,西里尔文,希伯来文,希腊文)的编码,但在拉丁文编码方面不太好(西方/中欧/东欧,土耳其语,越南语)并且根本不会弄阿拉伯语。

===============>>#2 票数:3

记事本使用字节顺序标记保存Unicode文件。 这意味着该文件的第一个字节将是:

  • EF BB BF - UTF-8
  • FF FE - “Unicode”(实际上是UTF-16小端,看起来像)
  • FE FF - “Unicode big-endian”(看起来像UTF-16大端)

其他文本编辑器可能会或可能不会有相同的行为,但如果您确定使用了记事本,这将为您提供一个体面的启发式来自动选择编码。 但是,所有这些序列在ANSI编码中都是有效的,因此这种启发式方法可能会出错。 无法保证使用正确的编码。

  ask by YSY translate from so

未解决问题?本站智能推荐:

1回复

在python中将Unicode转换为ANSI或UTF8

我正在使用Python 2.7.8,并且有一个脚本可以解析: myfile.txt具有UNICODE编码。 我如何向该脚本添加代码,以使其例如以ANSI的形式读取myfile.txt?
2回复

在Notepad ++中使用Python脚本将ANSI转换为UTF-8-Unicode名称问题

我正在使用村上淳写的脚本,将.srt文件(电影字幕)的编码从ANSI转换为UTF-8,效果很好,对我来说很完美,但是有问题。 我有一些名称中包含Unicode字符的文件夹,并且脚本在这些文件夹中无法打开.srt文件。 我只希望脚本像其他人一样打开这些文件夹。 这是脚本: 所以我
2回复

Windows API ANSI函数和UTF-8

是否可以使用带有UTF-8字符串的Windows API ANSI函数? 例如,假设我有一个以UTF-8编码的路径。 我可以调用CreateDirectoryA或CreateFileA并使用UTF-8路径,还是在调用函数之前必须执行一些转换?
1回复

如何在Python中同时读取ANSI和Unicode编码的文件

我试图使用Python编写一个函数,其中用户输入根目录和要搜索的关键短语。 然后,我的函数将搜索整个目录,以从包含已输入关键短语的文件中查找并输出行。 目前,我的脚本能够读取和输出使用ANSI编码的文件中的行,但不能读取Unicode。 请让我知道如何更改代码,以便我的脚本可以搜索两种类型
2回复

如何获取json文件的字符编码类型?

我想从jsoncpp获取json字符串的字符编码类型:UTF-8,ANSI还是UNICODE? 如何获取json :: value的字符编码类型? 谢谢前进!
3回复

在vbscript文件中键入双字节字符

我需要将→(&rarr)转换为我可以键入ANSI VBScript文件的符号。 我正在编写一个脚本,使用正则表达式将一组选定的htmlcodes转换为它们的实际双字节符号。 许多语言使用“\\ 0x8594;”来实现这一点...... VBScript中的等价是什么?
1回复

计数文件中的字母时出现意外结果

因此,当我遇到异常行为时,我正在编写一个用于静态密码分析的程序。 首先,我写了字符计数器,这就是问题所在。 我有文件: 当我尝试计算字母频率时,得到了一些有趣的结果! (不注意第一行,它只是说ifstream是开放的) 如您所见,程序说'z'在文本中出现了2次,但没
4回复

在任何时候,以UTF-8编码的文本永远不会给我们提供超过UTF-16编码的相同文本的+ 50%文件大小。 真假?

在某处我读过(改述): 如果我们比较UTF-8编码文件VS UTF-16编码文件,有时,UTF-8文件可能会使文件大小增加50%到100% 我是否正确地说这篇文章是错误的,因为在UTF-8中编码的文本在任何时候 都不会给我们提供超过UTF-16编码的相同文本的+ 50%文件大小
2回复

将文本文件的编码从utf-8转换为python中的ansi或unicode

我有一个utf-8编码的文本文件。 我想在python中将它的unicode更改为ANSI或unicode。 可能吗? 我该怎么做?
1回复

在Python中打印ANSI / UNICODE特殊字符

我已经使用Google搜索了30分钟,但找不到答案。 我如何自己打印这些字符? (我想避免使用诅咒等。)