Unicode文本的罗马化

26

我正在寻找一种方法,可以将任何语言的Unicode字母字符转换为带有重音的拉丁字母。目的是使外国人能够了解任何非拉丁文字写成的名称和单词的发音。

示例:

希腊语:Romanize("Αλφαβητικός") 返回 "Alphabētikós"(或 "Alfavi̱tikós")

日语:Romanize("しんばし") 返回 "shimbashi"(或 "sinbasi")

俄语:Romanize("яйца Фаберже") 返回 "yaytsa Faberzhe"(或 "jajca Faberže")

它应该支持以下脚本中的字符:CJK、Indic、Cyrillic、Semitic 和 Greek。它应该是数据驱动和可扩展的,使用来自 Unicode Consortium、美国、欧盟或联合国的数据。代码应该是开源的,用 .NET 或 Java 编写。

是否存在这样的库?


我正在寻找类似于Google Maps地名音译的东西,它使用ICU转换。希望Google能够开源该代码。(http://research.google.com/pubs/pub36450.html和http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/papers/36450.pdf) - Anthony Faull
2
@wberry:威尔士语本来就使用拉丁字母表,而拼音已经是罗马化的中文了。 - Michael Borgwardt
是的,但当您看到“乔治布什”的汉字时,您希望得到“George Bush”返回。 - bmargulies
4
如果你想要乔治·布什的翻译,那么你已经不是在寻找音译了,而是在寻找翻译。这个名字的通用音译应该是“qiáozhì bùshí”。原帖提到了“获取名字发音方面的见解”,因此我认为返回“George Bush”并没有什么帮助,中文发音是“qiáozhì bùshí”。 - Sprachprofi
这些示例来自http://cldr.unicode.org/index/cldr-spec/transliteration-guidelines。 - Kirill Bulygin
显示剩余2条评论
5个回答

19

这个问题比你想象的要复杂得多。

希腊文、西里尔文、印度文、格鲁吉亚文 -> 很简单,你可以在一个小时内编程完成。
泰语、日文假名 -> 需要更多的努力才能完成
日本汉字、中文 -> 这些不是字母/音节文字,所以实际上你并没有进行音译,而是需要在一个庞大的字典(EDICT和CCDICT应该可以)中查找每个符号的发音,并且很多时候如果没有考虑上下文,就会出错,尤其是在日本。
韩文 -> 技术上来说这是一个字母表,但计算机只能处理组合字符,因此你需要另外一个庞大的数据库,我不知道有哪些。
阿拉伯文、希伯来文 -> 这些语言不写短元音符号,所以很多时候你的音译将会是一些难以理解的东西,例如“bytlhm”(伯利恒)。我不知道是否有任何庞大的数据库将阿拉伯语或希伯来语的单词映射到它们的发音。


8
他实际上是这样说的:“它应该理想地支持以下文字的字符:CJK、Indic、Cyrillic、Semitic 和 Greek。”--> 阿拉伯语和希伯来语是最广泛使用的闪族语言。 - Sprachprofi
3
@Sprachprofi:关于你说的“希腊文、西里尔文、印度文字、格鲁吉亚文->微不足道”,你太天真了,认为你可以在一个小时内完成其中任何一种语言的转换。是的,你可以将每个西里尔文/希腊文/(以及无论印度文字是什么)字符映射到相应的拉丁字符集中。但这只是音译,而不是罗马化。根据前后字符的不同,你必须实现一个规则来确定如何进行罗马化。这比简单地音译字母难上一个数量级。此外,如果正确操作,你需要更长时间来完成音译。 - Stefan Steiger
@Sprachprofi:我能看到那段代码吗?你可以发布它(任何编程语言都可以)。我真的很感兴趣,因为我曾经尝试过将西里尔字母转换成罗马字母的名字,这让我头疼了很长时间,最后只好使用硬编码的键值查找(幸运的是,在选择名字时没有太多的变化)。 - Stefan Steiger
@StefanSteiger 这是俄罗斯护照中官方姓名罗马化的 Ruby 代码:def romanise(russian_name) ru_single = "АБВГДЕЁЗИЙКЛМНОПРСТУФЫЭабвгдеёзийклмнопрстуфыэ" la_single = "ABVGDEEZIIKLMNOPRSTUFYEabvgdeeziiklmnoprstufye" ru_double = %w(Ж ж Х х Ц Ч Ш Щ Ъ ц ч ш щ ъ Ю Я ю я) la_double = %w(Zh zh Kh kh Ts Ch Sh Shch Ie ts ch sh shch ie Iu Ia iu ia) s = russian_name.tr(ru_single, la_single) ru_double.each_with_index do |letter, i| s.gsub!(letter, la_double[i]) end s.gsub!(/[Ьь]/, '') s end - Sprachprofi
无法在字符限制内正确显示代码,因此请在此处尝试:https://replit.com/join/lcxvyxxsrq-judithmeyer - Sprachprofi
显示剩余6条评论

11
你可以使用 Unidecode Sharp

它是从 Python Unidecode 移植而来,而 Python Unidecode 则是从 Perl unidecode 移植而来。 (还有 PHPRuby 的实现可用)

用法:

using BinaryAnalysis.UnidecodeSharp;

.......................................

string _Greek="Αλφαβητικός";
MessageBox.Show(_Greek.Unidecode());

string _Japan ="しんばし";
MessageBox.Show(_Japan.Unidecode());

string _Russian ="яйца Фаберже";
MessageBox.Show(_Russian.Unidecode());

我希望这对你有好处。


1
+1,我只想指出,该库已经有Python和Perl的端口。 - Igor Chubin
谢谢,我已经下载了dll文件,但是Unidecode()仍然无法识别任何字符串。我不知道我必须使用BinaryAnalysis添加它... - Veverke

6

除了ICU,我不知道还有什么开源解决方案可供选择。如果ICU适合您,请使用它。如果不行,需要注意的是,我是一家销售商业产品的公司的首席技术官,我们的产品可以处理像中文词语、日文多重阅读和阿拉伯语不完整正字等繁琐情形。


@bmargulies 那个产品到底是什么?它是否提供 .NET API? - 41686d6564 stands w. Palestine
您想要查看的位置是www.basistech.com;是的,他们支持.NET。 - bmargulies


1

AnyAscii

在你的情况下,AnyAscii 这里也可能会有所帮助,因为它执行传统的罗马化。
他们还有网页演示
还有一个映射

与Unidecode相比,AnyAscii提供更好的结果,支持两倍多的字符,并且通常具有较小的文件大小。

用法

Console.WriteLine("Αλφαβητικός".Transliterate());
//Alfavitikos
        
Console.WriteLine("しんばし".Transliterate());
//shinbashi
        
Console.WriteLine("яйца Фаберже".Transliterate());
//yaytsa Faberzhe

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