2009-11-13 62 views
10

在红宝石中音译非英文字符的最简单方法是什么?这是转换,如:红宝石音译

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

+0

这似乎是我的早期问题的确切副本:http://stackoverflow.com/questions/225471/how-do-i-replace-accented-latin-characters-in-ruby –

回答

10

红宝石在其STDLIB的Iconv库,在一个非常相似的方式转换编码平时iconv命令

+1

是啊..'Iconv .iconv('ascii // ignore // translit','utf-8',string).to_s'完成这项工作。 – Selva

+1

我刚刚在OP的例子中试过这个,它返回了“Gvry”,而不是“Gevry”。 – jrdioko

+2

@jrdioko它应该是'Iconv.iconv('ascii // translit //忽略','utf-8',字符串)' – steenslag

3

从尝试采取看看this script用于替换字符串中重音字符的TechniConseils。使用示例:

"Gévry".removeaccents #=> Gevry 
+0

不适用于UTF-8字符串,至少对我而言。 – lzap

6

使用UnicodeUtils宝石。这适用于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(Normalization Form(K)ompatability Decomposition)格式的字符串。在 “E” 的unicode码点,被称为 “latin small letter e with acute”,可以以两种方式表示:

  • E = U + 00E9
  • E =(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字母。

+0

+1为分离字母重音,然后删除它们的巧妙方式。 -1没有正常化'我'作为'我' – nurettin