10

在ruby中音译非英文字符的最简单方法是什么。那就是转换,例如:

translit "Gévry"
#=> "Gevry"

4

3 回答 3

10

Ruby 在其 stdlib 中有一个Iconviconv库,它以与通常命令非常相似的方式转换编码

于 2009-11-13T00:57:31.763 回答
7

使用UnicodeUtils gem。这适用于 1.9 和 2.0。Iconv 在这些版本中已被弃用。

gem install unicode_utils

然后在 IRB 中试试这个:

2.0.0p0 :001 > require 'unicode_utils'  #=> true
2.0.0p0 :002 > r = "Résumé"             #=> "Résumé"
2.0.0p0 :003 > r.encoding               #=> #<Encoding:UTF-8>
2.0.0p0 :004 > UnicodeUtils.nfkd(r).gsub(/(\p{Letter})\p{Mark}+/,'\\1')
                                        #=> "Resume"

现在解释一下这是如何工作的!

首先,您必须以NFKD(规范化形式 (K) 兼容性分解)格式规范化字符串。“é” unicode 代码点,称为“带有锐音的拉丁小写字母 e ”,可以用两种方式表示:

  • é = U+00E9
  • é = (e = U+0065) + (急性 = U+0301)

第一种形式是最流行的单个代码点。第二种形式是分解格式,将字素(在屏幕上显示为“é”)分成两个基本代码点,即 ASCII“e”和重音符号。Unicode 可以由许多代码点组成一个字素,这在某些亚洲书写系统中很有用。

请注意,您通常希望以标准格式对数据进行规范化,以进行比较、排序等。在 ruby​​ 中,这里的“é”的两种格式不等于()。在 IRB 中,执行以下操作:

> "\u00e9"                   #=> "é"
> "\u0065\u0301"             #=> "é"
> "\u00e9" == "\u0065\u0301" #=> false
> "\u00e9" > "\u0065\u0301"  #=> true
> "\u00e9" >= "f"            #=> true  (composed é > f)
> "\u0065\u0301" > "f"       #=> false (decomposed é < f)

> "Résumé".chars.count       #=> 6
> decomposed = UnicodeUtils.nfkd("Résumé")  
                             #=> "Résumé"
> decomposed.chars.count     #=> 8
> decomposed.length          #=> 6
> decomposed.gsub(/(\p{Letter})\p{Mark}+/,'\\1')
                             #=> "Resume"

现在我们有了 NFKD 格式的字符串,我们可以使用“属性名称”语法 (\p{property_name}) 应用正则表达式来匹配一个字母后跟一个或多个变音符号“标记”。通过捕获匹配的字母,我们可以使用 gsub 将字母+变音符号替换为整个字符串中捕获的字母。

此技术从 ASCII 字母中删除了变音符号,并且不会将字符集(如希腊语或西里尔语字符串)音译为等效的 ASCII 字母。

于 2013-04-23T21:56:42.980 回答
3

试着看看TechniConseils 的这个脚本,它替换了字符串中的重音字符。使用示例:

"Gévry".removeaccents #=> Gevry
于 2009-11-13T01:06:31.833 回答