跳转到主要内容

Unicode文本的ASCII转写

项目描述

通常情况下,你会有Unicode格式的文本数据,但你需要将其表示为ASCII格式。例如,当你与不支持Unicode的旧代码集成时,或者为了便于在美式键盘上输入非罗马名字,或者当你从人类可读的Unicode字符串构建ASCII机器标识符时,仍需要具有一定的可读性。一个流行的例子是从文章标题生成URL别名。

Unidecode并不是在程序中为字符串完全支持Unicode的替代品。它的使用有一些注意事项,尤其是在其输出直接可见给用户时。在使用Unidecode之前,请阅读本README的其余部分。

在上面的多数示例中,你可以将Unicode字符表示为???\\15BA\\15A0\\1610,仅举两个极端例子。但这几乎对真正想阅读文本的人来说毫无用处。

Unidecode提供的解决方案是一条中间道路:函数unidecode()接收Unicode数据,并尝试用ASCII字符(即0x00至0x7F之间的通用可显示字符)来表示它,在映射两个字符集时所做的妥协被选为接近一个拥有美式键盘的人的选择。

结果的ASCII表示质量各不相同。对于西方起源的语言,它应该在完美和良好之间。另一方面,中文、日语或韩语等语言的转写(即在罗马字母中表示其他书写系统中的发音)是一个非常复杂的问题,而这个库甚至不尝试解决这个问题。它只做到字符级别的无上下文映射。因此,一个很好的经验法则是:你正在转写的脚本离拉丁字母越远,转写效果就越差。

通常,Unidecode产生的结果比简单地去除字符的符号(在Python中使用内置函数可以实现)要好。它基于手动调整的字符映射,例如,还包括符号和非拉丁字母的ASCII近似值。

请注意,有些人可能会觉得某些转写令人不快。最常见的情况是使用在多种语言中使用的字符。用户期望一个字符以他们的语言进行转写,但Unidecode使用的是另一种语言的转写。最好不要在用户直接可见的字符串中使用Unidecode。有关常见问题的更多信息,请参阅常见问题解答部分。

这是Sean M. Burke <sburke@cpan.org>的Perl模块Text::Unidecode的Python端口。

模块内容

这个库包含一个函数,该函数接受一个字符串对象,可能包含非ASCII字符,并返回一个可以安全编码为ASCII的字符串

>>> from unidecode import unidecode
>>> unidecode('kožušček')
'kozuscek'
>>> unidecode('30 \U0001d5c4\U0001d5c6/\U0001d5c1')
'30 km/h'
>>> unidecode('\u5317\u4EB0')
'Bei Jing '

您也可以为unidecode()指定一个errors参数,以确定Unidecode如何处理其转写表中不存在字符。默认值为'ignore',这意味着Unidecode将忽略这些字符(用空字符串替换它们)。'strict'将引发一个UnidecodeError。异常对象将包含一个index属性,可用于找到有问题的字符。'replace'将用'?'(或指定的其他字符串,指定在replace_str参数中)替换它们。'preserve'将保留原始的非ASCII字符。请注意,如果使用'preserve'unidecode()返回的字符串将不能编码为ASCII!

>>> unidecode('\ue000') # unidecode does not have replacements for Private Use Area characters
''
>>> unidecode('\ue000', errors='strict')
Traceback (most recent call last):
...
unidecode.UnidecodeError: no replacement found for character '\ue000' in position 0

还包括一个实用程序,允许您以多种方式从命令行转写文本

$ echo hello | unidecode
hello

从命令行参数

$ unidecode -c hello
hello

或从文件中读取

$ unidecode hello.txt
hello

实用程序使用的默认编码取决于您的系统区域设置。您可以使用-e参数指定另一个编码。有关所有可用选项的完整列表,请参阅unidecode --help

要求

除了Python本身之外没有任何要求。Unidecode支持Python 3.5或更高版本。

为了使Unidecode能够正确处理基本多语言平面(BMP)之外的字符,您需要一个带有“宽”Unicode字符(也称为“UCS-4构建”)的Python构建。BMP之外的常见字符包括用于数学符号的拉丁字母的粗体、斜体、手写体等变体。Unidecode不支持“窄”构建的代理对编码。

如果您的Python构建支持“宽”Unicode,则以下表达式将返回True

>>> import sys
>>> sys.maxunicode > 0xffff
True

有关Python中对“宽”Unicode字符的支持详情,请参阅PEP 261

安装

要从Python包索引安装Unidecode的最新版本,请使用以下命令:

$ pip install unidecode

要从源分布安装Unidecode并运行单元测试,请使用:

$ python setup.py install
$ python setup.py test

常见问题

德语变音符号被错误转写

带重音符号的拉丁字母“a”、“o”和“u”被Unidecode转写为“a”、“o”、“u”,而不是按照德语规则“ae”、“oe”、“ue”。这是故意的,并且不会改变。原因是这些字母在德语以外的语言中也使用(例如,芬兰语和土耳其语)。不带额外“e”的德语文本比使用德语规则的其它语言转写的文本更易读。一种解决方案是在将字符串传递给unidecode()之前自行替换这些字符。

日文汉字被错误转写为中文

与上述讨论的带重音符号的拉丁字母类似,Unicode标准编码的是字母,而不是特定语言中的字母或其含义。由于在日语和中文中,相同的字母可以根据使用的语言有非常不同的转写形式,因此这一点更为明显。由于Unidecode不进行特定语言的转写(见下一个问题),它必须决定使用其中之一。对于在日语和中文中都使用的某些字符,决定使用中文转写。如果您打算转写日文、中文或韩文文本,请考虑使用其他库,例如Unihandecode

Unidecode应该支持本地化(例如,语言或国家参数,检查系统区域设置等)

特定语言的转写是一个复杂的问题,超出了这个库的范围。与此相关联的更改不会被接受。请考虑使用其他库,这些库确实提供了此功能,例如Unihandecode

Unidecode应该自动检测要转写的文本的语言

语言检测是一个完全独立的问题,超出了这个库的范围。

Unidecode应使用类似MIT或BSD许可的宽松许可。

Unidecode的维护者认为,当基于许多贡献者的自愿工作构建产品时,要求提供源代码是公平合理的请求。如果许可证不适合您,请考虑使用其他库,例如text-unidecode

Unidecode产生的结果是完全错误的(例如,“u”带重音符号转写为“A 1/4”)

您传递给Unidecode的字符串在您的程序中的某个地方被错误解码了。例如,您可能将utf-8编码的字符串解码为latin1。如果终端、区域设置和/或文本编辑器配置不当,这可能不会立即明显。使用repr()检查您的字符串,并参考Unicode HOWTO

为什么Unidecode不替换字符串中的\u和\U转义序列?

Unidecode对转义序列一无所知。解释这些序列并在字符串字面量中将它们替换为实际的Unicode字符是Python解释器的任务。如果您提出这个问题,您很可能误解了这个库的目的。请参考Unicode HOWTO和标准库中的unicode_escape编码。

我升级了Unidecode,现在我网站上的一些URL返回404 Not Found。

这是运行您网站软件的问题,不是Unidecode的问题。偶尔,Unidecode库的新版本会被发布,其中包含对转写表的改进。这意味着您不能依赖Unidecode()的输出在不同版本的Unidecode库之间不会发生变化。如果您使用Unidecode()为您网站生成URL,请一次生成URL别名并存储在数据库中,或者锁定Unidecode的依赖关系到特定版本。

本节中的一些问题在这篇博客文章中进行了更详细的讨论。

性能说明

默认情况下,unidecode()针对大多数传递给它的字符串已经是ASCII且无需转写的情况进行优化(这个默认值在未来版本中可能会改变)。

对于性能关键的应用程序,还公开了两个额外的函数

unidecode_expect_ascii()针对仅ASCII输入进行了优化(在10个字符的字符串上比unidecode_expect_nonascii()快约5倍,在更长的字符串上更快),但对于非ASCII输入略慢。

unidecode_expect_nonascii()在ASCII和非ASCII输入上所需的时间大致相同,但对于非ASCII输入比unidecode_expect_ascii()略快。

除了运行时间上的差异外,这两个函数产生相同的结果。对于大多数Unidecode用户,性能差异应该是可以忽略不计的。

来源

您可以使用以下方式获取Unidecode的最新开发版本

$ git clone https://www.tablix.org/~avian/git/unidecode.git

此外,此存储库在GitHub上也有官方镜像:https://github.com/avian2/unidecode

联系

在联系维护者之前,请务必阅读上面的常见问题解答部分。

有关Unidecode的错误报告、补丁和建议可以发送到tomaz.solc@tablix.org

或者,您也可以在https://github.com/avian2/unidecode上提交一个票据或拉取请求

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

Unidecode-1.3.8.tar.gz (192.7 kB 查看哈希值)

上传时间: 源代码

构建分发

Unidecode-1.3.8-py3-none-any.whl (235.5 kB 查看哈希值)

上传时间: Python 3

支持者