2012-05-24 11 views
6

"quée"のような文字列を正規化する必要があり、é、á、íなどの拡張ASCII文字をローマ字/英語バージョンに変換できないようです。私はいくつかの異なる方法を試しましたが、これまで何も動作していません。この一般的な主題にはかなりの量の資料がありますが、私はこの問題の解決策を見つけることができません。ASCII文字の正規化

は、ここに私のコードです:

#transliteration solution (works great with standard chars but doesn't find the 
#special ones) - I've tried looking for both \x{130} and é with the same result. 
$mystring =~ tr/\\x{130}/e/; 

#converting into array, then iterating through and replacing the specific char 
#(same result as the above solution) 
my @breakdown = split("",$mystring); 

foreach (@breakdown) { 
    if ($_ eq "\x{130}") { 
     $_ = "e"; 
     print "\nArray Output: @breakdown\n"; 
    } 
    $lowercase = join("",@breakdown); 
} 

答えて

9

1)このarticle)は複雑な場合(かなり良い方法を提供する必要があります。

アクセント付きのすべてのUnicode文字をベース文字+アクセントに変換するソリューションを提供します。それが完了したら、単にアクセント文字を個別に削除することができます。


2)別のオプションは、CPANである:Text::Unaccent::PurePerlText::Unaccentの(改良された純粋なPerlバージョン)


3)も、this SO answerText::Unidecode提案:

$ perl -Mutf8 -MText::Unidecode -E 'say unidecode("été")' 
    ete 
+0

素敵な解決策、それは素晴らしい動作します!ありがとうございました! –

7

元のコードが機能しない理由は、帽子\x{130}はéではありません。それはLATIN CAPITAL LETTER I WITH DOT ABOVE (U+0130 or İ)です。 \x{E9}を意味するか、または\xE9(2桁の数字の場合は中かっこ)はLATIN SMALL LETTER E WITH ACUTE (U+00E9)です。

さらに、trにはバックスラッシュが追加されています。 tr/\xE9/e/のようになります。

これらの変更を加えれば、コードは機能しますが、CPANのモジュールの1つをこのような方法で使用することをお勧めします。私はアクセント付きの文字以上のものを扱うので、このためにはText::Unidecodeが好きです。

+1

ありがとうございました!私はあなたの変更を実装し、今は動作します。私は実際には、最もエレガントな方法だと思われるので、納入されたバージョンのモジュールを使用しています。 –

3

作業して再作業した後は、ここにいます。それは、入力文字列の途中にスペースを入れて単語を区別することを除いて、私が望むすべてのことをしています。

open FILE, "funnywords.txt"; 

# Iterate through funnywords.txt 
while (<FILE>) { 
    chomp; 

    # Show initial text from file 
    print "In: '$_' -> "; 

    my $inputString = $_; 

    # $inputString is scoped within a for each loop which dissects 
    # unicode characters (example: "é" splits into "e" and "´") 
    # and throws away accent marks. Also replaces all 
    # non-alphanumeric characters with spaces and removes 
    # extraneous periods and spaces. 
    for ($inputString) { 
     $inputString = NFD($inputString); # decompose/dissect 
     s/^\s//; s/\s$//;     # strip begin/end spaces 
     s/\pM//g;       # strip odd pieces 
     s/\W+//g;       # strip non-word chars 
    } 

    # Convert to lowercase 
    my $outputString = "\L$inputString"; 

    # Output final result 
    print "$outputString\n"; 
} 

ないのはなぜそれが赤の正規表現やコメントの一部を着色だ完全に確認してください...ここで

は "funnywords.txt" からのラインのいくつかの例です:

quée

22.

?éÉíóñúÑ¿¡

[.this? ]

AQUI、任意の残りのシンボルを取り除くことなく、s/\W+//gからs/[^a-zA-Z0-9 ]+//gにあなたの最後の正規表現を変更する文字と数字を維持に関するあなたの2番目の質問についてはアライ

2

を。残りの入力を正規化しているので、その正規表現を使用すると、-z、A-Z、0-9、または空白以外のものはすべて削除されます。最初に[]と^を使用すると、ブラケットの残りの部分にないすべてのものを探したいことが示されます。