ルビーで英語以外の文字を音訳する最も簡単な方法は何ですか。これは、次のような変換です。
translit "Gévry"
#=> "Gevry"
Rubyのstdlibには、通常のコマンドと非常によく似た方法でエンコーディングを変換するIconvライブラリがあります。iconv
UnicodeUtilsgemを使用します。これは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」として知られる「é」ユニコードコードポイントは、次の2つの方法で表すことができます。
最初の形式は、単一のコードポイントとして最も人気があります。2番目の形式は分解された形式で、書記素(画面に「é」として表示されるもの)を2つの基本コードポイントであるASCII「e」とアキュートアクセントマークに分割します。Unicodeは、多くのコードポイントから書記素を作成できます。これは、一部のアジアの書記体系で役立ちます。
通常、比較や並べ替えなどのために、データを標準形式で正規化する必要があることに注意してください。ルビーでは、ここでの「é」の2つの形式はequal()ではありません。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})を使用して正規表現を適用し、文字の後に1つ以上の発音区別符号「マーク」を一致させることができます。一致する文字をキャプチャすることにより、gsubを使用して、文字+発音区別符号を文字列全体でキャプチャされた文字に置き換えることができます。
この手法では、ASCII文字から発音区別符号が削除され、ギリシャ語やキリル文字列などの文字セットが同等のASCII文字に音訳されません。
文字列内のアクセント付き文字を置き換えるTechniConseilsのこのスクリプトを見てみてください。使用例:
"Gévry".removeaccents #=> Gevry