2011-12-15 4 views
32

文字列からアクセントを削除するために、(私の知る限り)java.text.Normalizerを持たない方法はありますか?例えば、「éàù」は「eau」になります。文字列からアクセントを削除する

可能であれば、文字列を解析して各文字を確認しないようにしたいと考えています。

+2

Androidは[java.text.Normalizer]あり(http://developer.android.com/reference/java/text:あなたが保存したい場合は、これらは、(stringを簡素化するための文字列である)、このコードを試してみてください/Normalizer.html)を使用している場合は、APIレベル9から開始します。 – eldarerathis

+2

http://stackoverflow.com/questions/6328654/android-2-3-and-java-text-normalizerの可能な複製 – cyborg

+1

ソートまたはマッチングする場合は、['Collat​​or'](http: /docs.oracle.com/javase/6/docs/api/java/text/Collat​​or.html)。結果を表示する必要がないかぎり、自分でアクセントを取り除くよりも優れています。 – erickson

答えて

74

java.text.Normalizerは、Androidには(最新版はとにかく)あります。あなたはそれを使うことができます。参考のため

EDIT、ここNormalizerを使用する方法である:

string = Normalizer.normalize(string, Normalizer.Form.NFD); 
string = string.replaceAll("[^\\p{ASCII}]", ""); 

(下のコメント欄にリンクから貼り付け)

+2

古いデバイスとの互換性のためにAPIレベル7でコードを作成しようとしていますが、それはそこにあるとは思わない – Johann

+0

アクセントを削除するために 'Normalizer.normalize'を呼び出す方法の例を投稿できますか? –

+0

私は将来の参照のための答えを編集しました – Guillaume

0

すべてのアクセント付きグラフ作成者は、10進値が127より大きい拡張ASCII文字コードセットです。文字列内のすべての文字を列挙できます。小数点文字コード値が127より大きい場合は、所望の同等物。アクセント付きの文字をアクセントのない相手に戻すのは簡単な方法ではありません。拡張された10進コードをアクセントのない文字にマップするために、ある種のマップをメモリに保持しなければなりません。

2

これはおそらく、最も効率的なソリューションではありませんが、それはやるだろうそれはすべてのAndroidバージョンで機能します:

private static Map<Character, Character> MAP_NORM; 
static { // Greek characters normalization 
    MAP_NORM = new HashMap<Character, Character>(); 
    MAP_NORM.put('ά', 'α'); 
    MAP_NORM.put('έ', 'ε'); 
    MAP_NORM.put('ί', 'ι'); 
    MAP_NORM.put('ό', 'ο'); 
    MAP_NORM.put('ύ', 'υ'); 
    MAP_NORM.put('ή', 'η'); 
    MAP_NORM.put('ς', 'σ'); 
    MAP_NORM.put('ώ', 'ω'); 
    MAP_NORM.put('Ά', 'α'); 
    MAP_NORM.put('Έ', 'ε'); 
    MAP_NORM.put('Ί', 'ι'); 
    MAP_NORM.put('Ό', 'ο'); 
    MAP_NORM.put('Ύ', 'υ'); 
    MAP_NORM.put('Ή', 'η'); 
    MAP_NORM.put('Ώ', 'ω'); 
} 

public static String removeAccents(String s) { 
    if (s == null) { 
     return null; 
    } 
    StringBuilder sb = new StringBuilder(s); 

    for(int i = 0; i < s.length(); i++) { 
     Character c = MAP_NORM.get(sb.charAt(i)); 
     if(c != null) { 
      sb.setCharAt(i, c.charValue()); 
     } 
    } 

    return sb.toString(); 
} 
4

私はラビの解決策を自分のニーズに合わせて調整しました。 ELPSの誰か:

private static Map<Character, Character> MAP_NORM; 
public static String removeAccents(String value) 
{ 
    if (MAP_NORM == null || MAP_NORM.size() == 0) 
    { 
     MAP_NORM = new HashMap<Character, Character>(); 
     MAP_NORM.put('À', 'A'); 
     MAP_NORM.put('Á', 'A'); 
     MAP_NORM.put('Â', 'A'); 
     MAP_NORM.put('Ã', 'A'); 
     MAP_NORM.put('Ä', 'A'); 
     MAP_NORM.put('È', 'E'); 
     MAP_NORM.put('É', 'E'); 
     MAP_NORM.put('Ê', 'E'); 
     MAP_NORM.put('Ë', 'E'); 
     MAP_NORM.put('Í', 'I'); 
     MAP_NORM.put('Ì', 'I'); 
     MAP_NORM.put('Î', 'I'); 
     MAP_NORM.put('Ï', 'I'); 
     MAP_NORM.put('Ù', 'U'); 
     MAP_NORM.put('Ú', 'U'); 
     MAP_NORM.put('Û', 'U'); 
     MAP_NORM.put('Ü', 'U'); 
     MAP_NORM.put('Ò', 'O'); 
     MAP_NORM.put('Ó', 'O'); 
     MAP_NORM.put('Ô', 'O'); 
     MAP_NORM.put('Õ', 'O'); 
     MAP_NORM.put('Ö', 'O'); 
     MAP_NORM.put('Ñ', 'N'); 
     MAP_NORM.put('Ç', 'C'); 
     MAP_NORM.put('ª', 'A'); 
     MAP_NORM.put('º', 'O'); 
     MAP_NORM.put('§', 'S'); 
     MAP_NORM.put('³', '3'); 
     MAP_NORM.put('²', '2'); 
     MAP_NORM.put('¹', '1'); 
     MAP_NORM.put('à', 'a'); 
     MAP_NORM.put('á', 'a'); 
     MAP_NORM.put('â', 'a'); 
     MAP_NORM.put('ã', 'a'); 
     MAP_NORM.put('ä', 'a'); 
     MAP_NORM.put('è', 'e'); 
     MAP_NORM.put('é', 'e'); 
     MAP_NORM.put('ê', 'e'); 
     MAP_NORM.put('ë', 'e'); 
     MAP_NORM.put('í', 'i'); 
     MAP_NORM.put('ì', 'i'); 
     MAP_NORM.put('î', 'i'); 
     MAP_NORM.put('ï', 'i'); 
     MAP_NORM.put('ù', 'u'); 
     MAP_NORM.put('ú', 'u'); 
     MAP_NORM.put('û', 'u'); 
     MAP_NORM.put('ü', 'u'); 
     MAP_NORM.put('ò', 'o'); 
     MAP_NORM.put('ó', 'o'); 
     MAP_NORM.put('ô', 'o'); 
     MAP_NORM.put('õ', 'o'); 
     MAP_NORM.put('ö', 'o'); 
     MAP_NORM.put('ñ', 'n'); 
     MAP_NORM.put('ç', 'c'); 
    } 

    if (value == null) { 
     return ""; 
    } 

    StringBuilder sb = new StringBuilder(value); 

    for(int i = 0; i < value.length(); i++) { 
     Character c = MAP_NORM.get(sb.charAt(i)); 
     if(c != null) { 
      sb.setCharAt(i, c.charValue()); 
     } 
    } 

    return sb.toString(); 

} 
2

ギョームの答えは動作しないが、それは文字列からすべて非ASCII文字が削除されます。

// Convert input string to decomposed Unicode (NFD) so that the 
// diacritical marks used in many European scripts (such as the 
// "C WITH CIRCUMFLEX" → ĉ) become separate characters. 
// Also use compatibility decomposition (K) so that characters, 
// that have the exact same meaning as one or more other 
// characters (such as "㎏" → "kg" or "ヒ" → "ヒ"), match when 
// comparing them. 
string = Normalizer.normalize(string, Normalizer.Form.NFKD); 

StringBuilder result = new StringBuilder(); 

int offset = 0, strLen = string.length(); 
while(offset < strLen) { 
    int character = string.codePointAt(offset); 
    offset += Character.charCount(character); 

    // Only process characters that are not combining Unicode 
    // characters. This way all the decomposed diacritical marks 
    // (and some other not-that-important modifiers), that were 
    // part of the original string or produced by the NFKD 
    // normalizer above, disappear. 
    switch(Character.getType(character)) { 
     case Character.NON_SPACING_MARK: 
     case Character.COMBINING_SPACING_MARK: 
      // Some combining character found 
     break; 

     default: 
      result.appendCodePoint(Character.toLowerCase(character)); 
    } 
} 

// Since we stripped all combining Unicode characters in the 
// previous while-loop there should be no combining character 
// remaining in the string and the composed and decomposed 
// versions of the string should be equivalent. This also means 
// we do not need to convert the string back to composed Unicode 
// before returning it. 
return result.toString(); 
+0

それは大文字を失う –

+0

もちろんです。大文字のままにしたい場合は、 'result.appendCodePoint(Character.toLowerCase(character));'の代わりに 'result.appendCodePoint(character);'を使用してください。 ;-) – alexander255