我使用第三方工具输出Unicode格式的文件。但是,我更喜欢它是ASCII。该工具没有设置来更改文件格式。如何使用Python将文件的格式从Unicode转换为ASCII?
什么是使用Python转换整个文件格式的最佳方式?
我使用第三方工具输出Unicode格式的文件。但是,我更喜欢它是ASCII。该工具没有设置来更改文件格式。如何使用Python将文件的格式从Unicode转换为ASCII?
什么是使用Python转换整个文件格式的最佳方式?
只需使用unicode
函数就可以很容易地转换文件,但是如果没有直接的ASCII等效代码,就会遇到Unicode字符问题。
This blog建议使用unicodedata
模块,该模块似乎处理粗略转换字符而没有直接相应的ASCII值,例如,
>>> title = u"Klüft skräms inför på fédéral électoral große"
通常被转换到
Klft skrms infr p fdral lectoral groe
这是非常错误的。但是,使用unicodedata
模块,其结果可能是更接近原文:
>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'
我认为这是一个比你意识到的更深的问题。简单地将文件从Unicode转换为ASCII很容易,但是,将所有Unicode字符转换为合理的ASCII对应文件(许多字母在两种编码中都不可用)是另一种。
这段Python的Unicode教程可以给你上发生了什么被转换为ASCII Unicode字符串一个更好的主意:http://www.reportlab.com/i18n/python_unicode_tutorial.html
下面是从网站的有用报价:
的Python 1.6也得到一个“统一” 内置功能,您可以 指定编码:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
所有这三个返回相同的 的事情,因为'你好' 中的字符是所有三种编码通用的。
现在让我们编码一个 欧洲口音,它不在 ASCII之内。你在控制台上看到的可能是 取决于您的操作系统 区域设置; Windows允许我输入ISO-Latin-1的 。
> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'
如果您无法键入急性字母e, 您可以输入字符串 '的Andr \ 202', 这是毫不含糊的。
Unicode支持所有常用的操作,如迭代和 拆分。我们不会在这里运行它们 。
像这样:但是
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
注意的是,这将失败与UnicodeDecodeError
异常,如果有不能被转换为ASCII的任何字符。
编辑:正如皮特卡尔刚才指出的,没有从Unicode到ASCII的一对一映射。所以有些角色根本无法以保留信息的方式进行转换。而且,标准的ASCII或多或少是UTF-8的一个子集,所以你甚至不需要做任何解码。
下面是一些简单的(和愚蠢的)代码做编码转换。我假设(但你不应该)输入文件是UTF-16(Windows简称'Unicode')。
input_codec = 'UTF-16'
output_codec = 'ASCII'
unicode_file = open('filename')
unicode_data = unicode_file.read().decode(input_codec)
ascii_file = open('new filename', 'w')
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec)))
请注意,如果Unicode文件中有任何不是ASCII字符的字符,这将不起作用。你可以做下面把无法识别的字符为s“?”:
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))
退房the docs了更加简单的选择。如果您需要做更复杂的事情,您可以在Python Cookbook上查看The UNICODE Hammer。
重要的是要注意,没有“统一”的文件格式是非常重要的。 Unicode可以通过几种不同的方式编码为字节。最常见的是UTF-8或UTF-16。你需要知道你的第三方工具正在输出哪一个。一旦你知道,不同的编码之间的转换是很容易的:
in_file = open("myfile.txt", "rb")
out_file = open("mynewfile.txt", "wb")
in_byte_string = in_file.read()
unicode_string = bytestring.decode('UTF-16')
out_byte_string = unicode_string.encode('ASCII')
out_file.write(out_byte_string)
out_file.close()
正如其他答复指出,你可能会想提供一个错误处理程序编码方法。使用'replace'作为错误处理程序很简单,但如果它包含无法用ASCII表示的字符,将会破坏文本。
正如其他海报指出,ASCII是Unicode的一个子集。
不过,如果你:
然后下面的例子显示了如何去做:
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>
对于我的问题,我只是想跳过非ASCII字符,只是输出仅ASCII输出,下面的解决方案的工作非常出色:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
顺便说一句,这是一个Linux命令iconv
做到这一点一种工作。
iconv -f utf8 -t ascii <input.txt >output.txt
感谢您指出了潜在的问题。但是,我不会冒着在输出文件的内容中存在不可转换的unicode字符的风险。它只是输出内部数据库的SQL模式,不包含任何超出正常范围的字符,即超出ASCII。 – 2008-10-06 17:35:33
@ Ray Vega:你现在知道了。这是一个错误和潜在的错误,假设unicode数据将只有ASCII字符。 – 2011-09-01 18:00:09