我使用第三方工具以Unicode格式输出文件。 但是,我更喜欢它是 ASCII。该工具没有更改文件格式的设置。
使用 Python 转换整个文件格式的最佳方法是什么?
您只需使用 unicode
函数即可轻松转换文件,但是如果没有直接的 ASCII 等效项,您会遇到 Unicode 字符的问题。
本博客推荐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" 内置功能,您可以 指定编码:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
所有这三个返回相同的 事情,因为《你好》中的角色 是所有三种编码的共同点。
现在让我们用 欧洲口音,在 ASCII.您在控制台上看到的内容可能会 取决于您的操作系统 现场;Windows允许我输入 ISO-拉丁语-1。
> >>> a = unicode('André','latin-1')
> >>> a u'Andr202'
如果您无法键入急性字母 e, 您可以输入字符串"Andr\202", 这是明确的。
Unicode 支持所有常见的 迭代和 分裂。我们不会碾过他们 这里。
便说一下,这些是iconv
执行此类工作的 linux 命令。
iconv -f utf8 -t ascii <input.txt >output.txt
这里有一些简单(和愚蠢)的代码来进行编码翻译。 我假设(但你不应该)输入文件是 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')))
查看文档以获取更简单的选择。 如果你需要做任何更复杂的事情,你可能希望查看Python Cookbook中的UNICODE Hammer。
像这样:
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
但请注意,如果有任何字符无法转换为 ASCII,此操作将失败并出现UnicodeDecodeError
异常。
编辑:正如Pete Karl刚刚指出的那样,从Unicode到ASCII没有一对一的映射。 因此,某些字符根本无法以信息保存的方式进行转换。 此外,标准ASCII或多或少是UTF-8的一个子集,因此您甚至不需要进行任何解码。
对于我只想跳过非 ascii 字符而只输出 ascii 输出的问题,以下解决方案效果非常好:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
重要的是要注意没有"Unicode"文件格式。 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()
如其他回复中所述,您可能希望向编码方法提供错误处理程序。 使用"替换"作为错误处理程序很简单,但如果文本包含无法用 ASCII 表示的字符,则会破坏文本。
正如其他海报所指出的,ASCII是Unicode的一个子集。
但是,如果您:
- 拥有旧版应用
- 您无法控制该应用的代码
- 您确定您的输入属于 ASCII 子集
然后下面的示例显示了如何做到这一点:
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>