24

我使用 3rd 方工具以 Unicode 格式输出文件。但是,我更喜欢它是 ASCII。该工具没有更改文件格式的设置。

使用 Python 转换整个文件格式的最佳方法是什么?

4

8 回答 8

44

只需使用该函数,您就可以轻松地转换文件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'
于 2008-10-06T17:21:15.790 回答
11

我认为这是一个比你意识到的更深层次的问题。简单地将文件从 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'
> >>>

所有这三个都返回相同的东西,因为 'Hello' 中的字符对于所有三种编码都是通用的。

现在让我们用 ASCII 之外的欧洲口音编码一些东西。您在控制台上看到的内容可能取决于您的操作系统区域设置;Windows 让我输入 ISO-Latin-1。

> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'

如果不能输入锐角字母 e,可以输入字符串 'Andr\202',这是明确的。

Unicode 支持所有常见的操作,例如迭代和拆分。我们不会在这里碾压他们。

于 2008-10-06T17:17:01.010 回答
4

顺便说一句,这些是iconv执行此类工作的 linux 命令。

iconv -f utf8 -t ascii <input.txt >output.txt
于 2011-12-17T09:29:58.033 回答
2

像这样:

uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')

但是请注意,如果有任何字符无法转换为 ASCII ,这将失败并出现异常。UnicodeDecodeError

编辑:正如皮特卡尔刚刚指出的那样,从 Unicode 到 ASCII 没有一对一的映射。因此,某些字符根本无法以保留信息的方式进行转换。此外,标准 ASCII 或多或少是 UTF-8 的子集,因此您甚至不需要进行任何解码。

于 2008-10-06T17:18:04.627 回答
2

这是一些简单(愚蠢)的代码来进行编码转换。我假设(但您不应该)输入文件采用 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 字符的字符,这将不起作用。您可以执行以下操作将无法识别的字符转换为“?”:

ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))

查看文档以获得更简单的选择。如果您需要做任何更复杂的事情,您可能希望查看Python Cookbook 中的The UNICODE Hammer

于 2008-10-06T17:24:48.933 回答
2

对于我只想跳过非 ascii 字符而只输出 ascii 输出的问题,以下解决方案非常有效:

    import unicodedata
    input = open(filename).read().decode('UTF-16')
    output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
于 2011-06-10T21:08:02.803 回答
0

请务必注意,没有“Unicode”文件格式。Unicode 可以通过几种不同的方式编码为字节。最常见的是 UTF-8 或 UTF-16。您需要知道您的第 3 方工具输出的是哪一个。一旦你知道了,不同编码之间的转换就很容易了:

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()

如其他回复中所述,您可能希望为 encode 方法提供一个错误处理程序。使用 'replace' 作为错误处理程序很简单,但如果它包含无法用 ASCII 表示的字符,则会破坏您的文本。

于 2008-10-06T20:24:46.233 回答
0

正如其他海报所指出的,ASCII 是 unicode 的子集。

但是,如果您:

  • 有一个旧版应用程序
  • 您无法控制该应用程序的代码
  • 您确定您的输入属于 ASCII 子集

然后下面的例子展示了如何做到这一点:

mystring = u'bar'
type(mystring)
    <type 'unicode'>

myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
    <type 'str'>
于 2009-12-15T09:12:38.657 回答