2015-06-09 5 views
9

Ich möchte den Kleinbuchstaben von "I" von Englisch (i) mit Kleinbuchstaben von "İ" von Türkisch (i) übereinstimmen. Sie sind die gleiche Glyphe, aber sie passen nicht zusammen. Wenn ich System.out.println("İ".toLowerCase()); das Zeichen i und ein Punkt gedruckt wird (diese Website zeigt es nicht richtig)Wie kann ich "i" mit Türkisch in Java vergleichen?

Gibt es eine Möglichkeit, diese zu vergleichen? (Am besten ohne es hart zu codieren) Ich möchte das Programm übereinstimmen das gleiche Glyphen unabhängig von der Sprache und dem UTF-Code. Ist das möglich?

Ich habe die Normalisierung ohne Erfolg getestet.

public static void main(String... a) { 
    String iTurkish = "\u0130";//"İ"; 
    String iEnglish = "I"; 
    prin(iTurkish); 
    prin(iEnglish); 
} 

private static void prin(String s) { 
    System.out.print(s); 
    System.out.print(" - Normalized : " + Normalizer.normalize(s, Normalizer.Form.NFD)); 
    System.out.print(" - lower case: " + s.toLowerCase()); 
    System.out.print(" - Lower case Normalized : " + Normalizer.normalize(s.toLowerCase(), Normalizer.Form.NFD)); 
    System.out.println(); 

} 

Das Ergebnis wird in dem Ort, aber die erste Zeile (iTurkish) hat immer noch die ̇ in der Nähe von Klein i nicht richtig dargestellt.

Zweck und Problem

Das wird eine mehrsprachige Wörterbuch sein. Ich möchte, dass das Programm erkennen kann, dass "IFEL" mit "if" beginnt. Um sicherzustellen, dass sie nicht die Groß-/Kleinschreibung beachten, konvertiere ich zuerst beide Texte in Kleinbuchstaben. IFEL wird i (dot) fel und „wenn“ nicht als Teil erkannt wird,

+2

Die beiden Buchstaben sind nicht der gleiche uni Code sehen, so dass sie nicht übereinstimmt. – Zelldon

+1

Sie können diakritische Zeichenfolgen mit [commons-lang] entfernen (https://commons.apache.org/proper/commons-lang/): org.apache.commons.lang3.StringUtils.stripAccents (String) – agad

+0

@agad Wouldn verhindere es die Unterscheidung von I von I? Ich würde es in Erwägung ziehen, wenn es dazu keine Möglichkeit gibt. – WVrock

Antwort

9

Wenn Sie aus dem Hex-Wert des Zeichens gedruckt werden Sie sehen, der Unterschied ist klar:

İ 0x130 - Normalized : İ 0x49 0x307 - Lower case: i̇ 0x69 0x307 - Lower case Normalized : i̇ 0x69 0x307 
I 0x49 - Normalized : I 0x49 - Lower case: i 0x69 - Lower case Normalized : i 0x69 

Normalisierung der türkischen İ gibt Ihnen kein Englisch I, stattdessen gibt es Ihnen ein Englisch I gefolgt von einem diakritischen, 0x307. Dies ist richtig und zu erwarten durch den Normalisierungsprozess. Die Normalisierung ist keine Operation "In ASCII konvertieren". Wie die Dokumentation für Normalizer erwähnt, ist der Prozess, den es folgt, ein sehr streng definierter Standard, der Unicode Standard Annex #15 — Unicode Normalization Forms.

Es gibt numerous ways to strip diacritics, entweder vor oder nach der Normalisierung. Was Sie brauchen, wird auf die Besonderheiten Ihres Anwendungsfall abhängen, sondern auch für Ihren Anwendungsfall würde ich mit Guava ‚s CharMatcher Klasse vorschlagen Nicht-ASCII-Zeichen Streifen nach Normalisierung, zB:

String asciiString = CharMatcher.ASCII.retainFrom(normalizedString); 

This answer geht in mehr Tiefe über was \p{InCombiningDiacriticalMarks} tut, und warum es nicht ideal ist. Meine CharMatcher Lösung ist auch nicht ideal (die verknüpfte Antwort bietet robustere Lösungen), aber für eine schnelle Lösung finden Sie möglicherweise nur ASCII-Zeichen "gut genug". Dies ist sowohl näher an "korrekt" als auch schneller als der Pattern basierte Ansatz.

+1

+1, Interessanter Nebeneffekt '" İ ".toLowerCase()' scheint zu entscheiden, dass es das Zeichen zerlegen muss. Zumindest hier ... – dhke

+0

Jeder scheint zu empfehlen Diakritika zu strippen. Ich werde es wahrscheinlich so machen. Ich denke, "if" mit "iF" zu vergleichen ist besser, als "if" mit "iF" zu vergleichen. Tough ich bin mir nicht sicher, ob das der Fall wäre. – WVrock

+1

@WVrock - wie Sie es vorgestellt haben, ist die beste Lösung für Ihr Problem, die diakritischen Zeichen zu entfernen. Es ist möglich, dass Sie zusätzliche Anforderungen haben, die Sie uns nicht mitgeteilt haben, die eine andere Lösung rechtfertigen könnten. Aber im Allgemeinen, wenn Sie wollen, dass jemand englische Zeichen tippen und sie türkischen zuordnen kann, müssen Sie * einige * Informationen entfernen, und Sie werden sich schwer tun, sowohl falsch positive als auch falsche negative zu vermeiden . Ihre Lösung sollte versuchen, den für Ihren Anwendungsfall schlechteren Wert zu minimieren. – dimo414

-1

können Sie den Code verwenden Gebrüll:

public static void main(String... a) { 

     String iTurkish = "\u0130";//"İ"; 
     String iEnglish = "I"; 
     prin(iTurkish); 
     prin(iEnglish); 


} 

private static void prin(String s) { 
    System.out.print(s); 
    String nfdNormalizedString = Normalizer.normalize(s, Normalizer.Form.NFD); 
    Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); 
    System.out.print(" - Normalized : " + pattern.matcher(nfdNormalizedString).replaceAll("")); 
    System.out.print(" - lower case: " + s.toLowerCase()); 
    System.out.print(" - Lower case Normalized : " + Normalizer.normalize(pattern.matcher(nfdNormalizedString).replaceAll("").toLowerCase(), Normalizer.Form.NFD)); 
    System.out.println(); 

} 

Oder Converting Symbols, Accent Letters to English Alphabet

+0

Nicht wirklich nett, Code aus der Utils-Klasse zu kopieren und hier als eigene darzustellen. – agad

+0

Warum keine Stimme? Ich habe den Link "http://stackoverflow.com/questions/1008802/converting- Symbols-accent-letters-to-Englisch-alphabet" zur Verfügung gestellt. Haben Sie es nicht gesehen? "agad" – Rafiq

+0

+1 für einen Link zu der Antwort und Anpassung an den angegebenen Code. Auch wenn es besser wäre, wenn Sie zuerst den Link bereitgestellt hätten und dann klargestellt hätten, dass Sie den Code von jemand anderem verwenden. – WVrock

Verwandte Themen