2009-11-13 61 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