1

次のリンクを使用して、キーのハッシュマップを作成しています = 文字の unicode 値と値がマップする実際の文字です - https://github.com/lmjabreu/solr-conftemplate/blob/master/mapping-ISOLatin1Accent. TXT

これまでのところ、文字列からアクセントを削除する次のコードを作成しました

public class ACCENTS {

    public static void main(String[] args){

        // this is the hashmap that stores the mappings of the characters to their ascii equivalent
        HashMap<Character, Character> characterMappings = new HashMap<>();

        characterMappings.put('\u00C0', 'A');
        characterMappings.put('\u00C1', 'A');
        characterMappings.put('\u00C2', 'A');
        characterMappings.put('\u00C3', 'A');
        characterMappings.put('\u00C4', 'A');
        characterMappings.put('\u00C5', 'A');
        characterMappings.put('\u00C7','C');
        characterMappings.put('\u00C8', 'E');
        characterMappings.put('\u00C9','E');
        characterMappings.put('\u00CA', 'E');
        characterMappings.put('\u00CB', 'E');
        characterMappings.put('\u00CC', 'I');
        characterMappings.put('\u00CD', 'I');
        characterMappings.put('\u00CE', 'I');
        characterMappings.put('\u00CF', 'I');
        characterMappings.put('\u00D0', 'D');
        characterMappings.put('\u00D1', 'N');
        characterMappings.put('\u00D2', 'O');
        characterMappings.put('\u00D3', 'O');
        characterMappings.put('\u00D4', 'O');
        characterMappings.put('\u00D5', 'O');
        characterMappings.put('\u00D6', 'O');
        characterMappings.put('\u00D8', 'O');
        characterMappings.put('\u00D9', 'U');
        characterMappings.put('\u00DA', 'U');
        characterMappings.put('\u00DB', 'U');
        characterMappings.put('\u00DC', 'U');
        characterMappings.put('\u00DD', 'Y');
        characterMappings.put('\u0178', 'Y');
        characterMappings.put('\u00E0', 'a');
        characterMappings.put('\u00E1', 'a');
        characterMappings.put('\u00E2', 'a');
        characterMappings.put('\u00E3','a');
        characterMappings.put('\u00E4', 'a');
        characterMappings.put('\u00E5', 'a');
        characterMappings.put('\u00E7', 'c');
        characterMappings.put('\u00E8', 'e');
        characterMappings.put('\u00E9', 'e');
        characterMappings.put('\u00EA','e');
        characterMappings.put('\u00EB', 'e');
        characterMappings.put('\u00EC', 'i');
        characterMappings.put('\u00ED', 'i');
        characterMappings.put('\u00EE', 'i');
        characterMappings.put('\u00EF', 'i');
        characterMappings.put('\u00F0', 'd');
        characterMappings.put('\u00F1','n' );
        characterMappings.put('\u00F2', 'o');
        characterMappings.put('\u00F3', 'o');
        characterMappings.put('\u00F4', 'o');
        characterMappings.put('\u00F5', 'o');
        characterMappings.put('\u00F6', 'o');
        characterMappings.put('\u00F8', 'o');
        characterMappings.put('\u00F9', 'u');
        characterMappings.put('\u00FA', 'u');
        characterMappings.put('\u00FB', 'u');
        characterMappings.put('\u00FC', 'u');
        characterMappings.put('\u00FD', 'y');
        characterMappings.put('\u00FF', 'y');

        String token = "nа̀ра";
        String newString = "";


        for(int i = 0 ; i < token.length() ; ++i){
            if( characterMappings.containsKey(token.charAt(i)) )
                newString += characterMappings.get(token.charAt(i));
            else
                newString += token.charAt(i);
        }

        System.out.println(newString);
    }
}

期待される結果は「napa」だったはずですが、変換が実行されていないことが判明しました。

4

2 に答える 2

5

HashMap を使用する理由がわかりません。しかし、分音符号を削除したいだけなら、おそらくこれが役立ちます:

String s = "nа̀ра";
s = Normalizer.normalize( s, Normalizer.Form.NFD );
s = s.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
System.out.println( s );

--> ナパ

(HashMap の使用を主張する場合は、他の方向でも機能する可能性があるため、'Normalizer' クラスを参照する必要があります。)

この記事から引用: http://blog.smartkey.co.uk/2009/10/how-to-strip-accents-from-strings-using-Java-6/

于 2013-09-27T17:34:27.047 に答える
1

Java の最も醜い「機能」のいくつかに出くわしました: 1 つの Unicode 文字が、文字のタペル (およびトリプル) で表される場合があります。

実際、トークンの長さは 5 文字です。á は 2 つの文字の組み合わせであり、文字列としてのみ表すことができます。

これが理由です

 characterMappings.put('а̀`', 'y'); //(accent can't be displayed correctly in code-mode, try it yourself)

コンパイルされません。

ここにもっと説明があります。

私の謙虚な意見では、String は Java で最悪のクラスの 1 つです。特に「非標準」文字を使用する場合。

問題を解決するには、マップをMap<String,String>またはに変更することをお勧めしますMap<String,Character>。このようにして、「文字」をマップでき、エスケープされた Unicode 文字を無視すると、コードが読みやすくなります。

詳細については、HighSurrogate または CodePoint を Google で検索してください。CodePoints は有効な (= 表示可能な) char-sequences であり、前に述べたように、必ずしも String 内の文字数に対応する必要はありません。

Java-Character はわずか 2 バイト幅なので、これが必要です。すべての Unicode 文字に対して小さいですが、ほとんどの場合 (= 標準のラテン文字を使用している限り)十分な大きさです。

編集:

を使用してもMap<String,String>、コードは機能しません。文字をループするためです。しかし、単一の Java 文字が特殊な Unicode 文字と一致することはありません。

これは役立つかもしれませんが、どのような状況でも機能しない可能性があります (結局のところ、Java 文字列は厄介です)。

HashMap<String, String> characterMappings = new HashMap<>();
characterMappings.put("а̀", "a");

String token = "nа̀ра";
String newString = "";

for (Entry<String, String> e : characterMappings.entrySet()) {
    token = token.replaceAll(e.getKey(), e.getValue());
}
System.out.println(token);

編集 2

コードをコメントとして投稿するのは面倒なので:

    String s = "brûlée";
    String s1 = Normalizer.normalize(s, Normalizer.Form.NFKD);
    String regex = "[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+";

    String s2 = new String(s1.replaceAll(regex, "").getBytes("ascii"),
            "ascii");

    System.out.println(s2);

これは、これまでに試したすべてのもので機能します。それでも@Scheintodは称賛に値します。ソースはこちら

よろしくお願いします

サム

于 2013-09-27T17:07:00.373 に答える