2016-11-25 11 views
0

アクセントを無視した正規表現を作成したいと思います。例えばRegexOptions.CultureInvariantアクセントに一致するものが見つかりません

string s = "I am an old élephant"; 
string pattern = "elephant"; 
bool result = new Regex(pattern, RegexOptions.CultureInvariant).IsMatch(s); 

私の文化私はテストです:

System.Globalization.CultureInfo.CurrentCulture = Fr-fr 

だから私は、一致を見つけるために、このコードを期待しているだろうが、それはしていません。

これに簡単にマッチする方法はありますか?

私はélèphântをElephantに置き換えるStringReplaceオーバーロードメソッドを作成しようとしています。

+4

"私がテストしたときの私の文化は、あなたが' RegexOptions.CultureInvariant'を指定したので無関係です。 – hvd

+1

@ A.D。 http://stackoverflow.com/questions/249087/how-do-i-remove-diacritics-accents-from-a-string-in-net –

答えて

4

使用方法次

public string removeDiacritics(string str) 
    { 
     var sb = new StringBuilder(); 

     foreach (char c in str.Normalize(NormalizationForm.FormD)) 
     { 
      if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) 
      { 
       sb.Append(c); 
      } 
     } 
     return sb.ToString().Normalize(NormalizationForm.FormC); 
    } 

そして、それは

 string s = "I am an old élephant"; 
     string pattern = "elephant"; 
     bool result = new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(removeDiacritics(s)); //true 

た場合に動作しますあなたは何かを置き換える必要があります。 matchcollectionを(逆方向に)繰り返し、それぞれの一致のインデックスに応じて元の文字列を編集します。

、について説明:(私は、文字列「私は古い象だ」使用しています)

のリストに、元の文字列のすべての文字を書いてみましょう:

foreach (char c in str) 
{ 
    chars1.Add(c); 
} 

enter image description here

として、 charがUnicode char 233または00E9として定義されていることがわかります(http://unicode-table.com/de/#00E9参照)

ここで正規化について説明します

documentionが言うように: フォームD:

char型のEはEとアクセント文字の中に "分割" されていることを意味
Indicates that a Unicode string is normalized using full canonical decomposition. 

ことを確認するには、聞かせての出力正規化された文字列の文字は:

List<char> chars2 = new List<char>(); 
foreach(char c in str.Normalize(NormalizationForm.FormD)) 
{ 
    chars2.Add(c); 
} 
時計に見られるように

enter image description here

、Eは今や101(\ u0065)+ 2つの文字(に正規化されます 正規化された文字列のすべての文字を繰り返し処理し、 "NonSpacingMark"の場合はStringBuilderに追加します。

MSDN: https://msdn.microsoft.com/en-us/library/system.globalization.unicodecategory(v=vs.110).aspx

NonSpacingMark基本文字の修飾を示す

ノンスペーシング文字。 ユニコード指定「Mn」(マーク、スペースなし)で示されます。 値は、今私たちの文字列に2つのまたは3文字のように定義されている他のすべての文字は、Unicodeの文字記号に「変換」になっていることを確認するために、最後に5.

で、私たちは私たちの新しいを正規化する必要があります文字列をFormCに戻します。

MSDN: FormC:

が可能な場合、それらの 主要複合材を有する配列の置換に続いて、Unicode文字列を完全正規 分解を用いて正規化されていることを示します。

+0

それは動作します。このためのThx: –

+0

@ user1519979:多分あなたはそれがどのように動作するかを精緻化する必要があります。あなたがやっていることを理解していますが、誰もがしているとは確信していません。 – Sefe

+0

@Sefe done ..;) – user1519979

1

バリアント正規表現を指定しています。つまり、あなたの文化はのように無視されます。だから...

bool result = new Regex(pattern).IsMatch(s); 

をオプションを削除する必要が...またはあなたが文化に依存しないようにしたい場合は、あなたのパターンを拡張し、次のいずれか

string pattern = "[eé]lephant"; 
+0

デフォルトでは、RegexOptions.CultureInvariantを使用しないと動作しません。 私の理解はRegexOptions.CultureInvariantタグはそれにマッチするだろうが、私は誤解しました。 –

+0

文字列パターン= "[eé] lephant";文字列とアクセントをアクセントなしの文字列と比較する際に、一致するものを見つけるための一般的なメソッドを探しているので、私が探しているものではありません。 私は実際にエレファントとélèphântを置き換えるStringReplaceオーバーロードメソッドを作成しようとしています。 –

+0

したい場合は、 'String.Equals'を使います。そこにあなたの文化を指定することができます。正規表現は完全一致であなたを助けます;文化に敏感な検索ではそれほど有用ではありません。あなたはまた、その種の情報を提供するためにあなたの質問を更新する必要があります。 – Sefe

0

正規表現を使用する場合は、\P{L}を使用して、指定されたユニコードチャプターが文字であることを指定できます。

 string s = "I am an old ùûüÿàâçéèêëïîô"; 
     string pattern = @"(\p{L})"; 
     var regex = new Regex(pattern); 
     var result = regex.Replace(s, @"$1"); 
     Console.WriteLine(result);//I am an old uuuyaaceeeeiio 
関連する問題