如何在Perl中将UTF8编码的非ASCII字符转换为ASCII等效字符?

5
我有一个Perl脚本,由第三方调用来发送注册我的软件的人的姓名。其中一些方面会使用UTF-8编码这些名称,因此我已经相应地修改了我的脚本,使用Encode::decode_utf8(...)将UTF-8解码为ASCII。
通常情况下,这个方法是有效的,但每隔6个月左右,其中一个名称包含西里尔字母、希腊字母或罗马尼亚字符,因此对该名称进行解码会导致垃圾字符,例如“ПодражанÑкає。我必须跟进客户,并要求他提供他的姓名的“拉丁字符版本”,以便发放注册码。
那么,是否有任何Perl模块可以检测是否存在这样的字符,并在必要时自动将它们转换为最接近的ASCII表示形式?
似乎我可以使用Lingua::Cyrillic::Translit::ICAO加上Lingua::DetectCharset来处理西里尔字母,但我更喜欢能够处理其他字符集的东西。
4个回答

10
我认为您可以使用 Text::Unidecode 来实现此功能,这正是它所尝试的。

1
在Text::Unicode的文档中,"注意事项"下出现了这个错误的短语:
确保输入数据确实是utf8字符串。
UTF-8是一种可变长度编码,而Text::Unidecode仅接受每个字符的固定长度(两个字节)编码。所以该句应改为:
确保输入数据确实是由两个字节的Unicode字符组成的字符串。
这也称为UCS-2。
如果您想转换真正是utf8的字符串,则可以按以下方式执行:
my $decode_status = utf8::decode($input_to_be_converted);
my $converted_string = unidecode ($input_to_be_converted);

0

如果你需要处理不在 ASCII 范围内的 UTF-8 数据,最好的方法是更改后端代码,使其能够处理 UTF-8 数据。那么如何将汉字转写成罗马字呢?


在超过10年的共享软件开发中,我只有少数来自日本和中国的客户。为了解决一个轻微的烦恼,启用我所有的共享软件程序的Unicode功能是夸张的。在这种情况下,我更多地寻求一种快速且简单的方法。 - Adrian Grigore
也许(只是也许),如果您启用utf-8,您可能会找到更多的客户? - innaM
一些:可以。但是很多且值得开发的:不行。盗版在共享软件业务中是一个非常大的问题,特别是在像中国这样的国家。日本市场还不错,但从其他共享软件作者那里听到的消息是,除非你有一个真正的大作品,否则通常不值得投入时间和精力。 - Adrian Grigore

0

如果你得到的是西里尔文本,对于许多字符来说,没有“最接近的ASCII表示”。


+1. 拼音转换并不是简单地替换单个字符。要么正确支持 Unicode,要么仅支持 ASCII;介于两者之间的任何事情都会很快变得混乱。 - bobince
然而,每当我问一个来自俄罗斯的人他的名字时,他都能提供其拉丁字符版本。我知道有些字符只是粗略的近似,但显然必须有解决我的问题的方法。 - Adrian Grigore
嗯,有些给你的拉丁语等效名称并不是他们的“真实”名称。 - brian d foy
他们提供给你的是一种发音他们名字的方式——转录,而你正在寻找的是音译,这是一个不同的问题。 - Nemanja Trifunovic
我同意。如果这些字符有ASCII/Latin等价物,他们就不必首先发明Unicode了。 - AmbroseChapel
我出生在罗马尼亚,所以我知道他们给我的不是他们的真名。但在这种情况下,“足够接近”就可以了。从商业角度来看,为了迎合不到0.1%的用户而添加Unicode支持是没有意义的。我倒不如实现一些更有用的东西。 - Adrian Grigore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接