Java Regex für die Unterstützung von Unicode?

80

Um A bis Z abzugleichen, verwenden wir Regex:

[A-Za-z]

Wie kann man zulassen, dass Regex mit den vom Benutzer eingegebenen utf8-Zeichen übereinstimmt? Zum Beispiel chinesische Wörter wie 环保 部

Cometta
quelle
2
In Java 7 wird Unicode-Regex mit UNICODE_CHARACTER_CLASSFlag oder Embeddable unterstützt (?U). Siehe stackoverflow.com/questions/4304928/…
Alastair McCormack

Antworten:

120

Was Sie suchen, sind Unicode-Eigenschaften.

zB \p{L}ist jede Art von Brief aus jeder Sprache

Ein Regex, der zu einem solchen chinesischen Wort passt, könnte so etwas wie sein

\p{L}+

Es gibt viele solcher Eigenschaften. Weitere Informationen finden Sie unter reguläre-Ausdrücke.info

Eine andere Möglichkeit ist die Verwendung des Modifikators

Pattern.UNICODE_CHARACTER_CLASS

In Java 7 gibt es eine neue Eigenschaft Pattern.UNICODE_CHARACTER_CLASS, die die Unicode-Version der vordefinierten Zeichenklassen aktiviert. Weitere Details und Links finden Sie in meiner Antwort hier

Sie könnten so etwas tun

Pattern p = Pattern.compile("\\w+", Pattern.UNICODE_CHARACTER_CLASS);

und \wwürde alle Buchstaben und alle Ziffern aus beliebigen Sprachen (und natürlich einige Wörter, die Zeichen wie kombinieren _) übereinstimmen .

Stema
quelle
Müssen wir den Mustervergleicher anweisen, die diakritischen Zeichen zu kombinieren, um Wörter wie Da̱nx̱a̱laga̱litła̱n zu finden?
Dave Jarvis vor
9

Um einzelne Zeichen abzugleichen, können Sie sie einfach als Literale oder über die \u03FBSyntax in eine Zeichenklasse aufnehmen .

Offensichtlich können Sie oft nicht alle zulässigen Zeichen in ideografischen Sprachen auflisten. Damit der Regex Unicode-Zeichen entsprechend ihrem Typ oder Codeblock behandelt, werden verschiedene andere Escapezeichen unterstützt, die hier definiert sind . Schauen Sie sich den Abschnitt "Unicode-Unterstützung" an, insbesondere die Verweise auf die CharacterKlasse und auf den Unicode-Standard selbst.

Kilian Foth
quelle
wie man mehrere vom Benutzerbeispiel eingegebene utf8-Zeichen zusammenfügt 环保 部, weil der Benutzer zufällig eine Anzahl von Zeichen
eingibt
1
Es ist so, als würde man mehrere lateinische Zeichen abgleichen: [a-z]+oder [a-z]{3}oder sogar [a-z]{2,10}. Der einzige Unterschied besteht darin, was Sie in der Zeichenklasse zulassen, für die der Quantifizierer gilt.
Kilian Foth
9

Um die NLS-Unterstützung anzusprechen und die Annahme von englischen Sonderzeichen zu vermeiden, können wir das folgende Muster verwenden ...

[a-zA-Z0-9 \ u0080- \ u9fff] * +

Referenz zum UTF-Codepunkt: http://www.utf8-chartable.de/unicode-utf8-table.pl

Code-Auszug:

    String vowels = "అఆఇఈఉఊఋఌఎఏఐఒఓఔౠౡ";
    String consonants = "కఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహ";
    String signsAndPunctuations = "కఁకంకఃకాకికీకుకూకృకౄకెకేకైకొకోకౌక్కౕకౖ";
    String symbolsAndNumerals = "౦౧౨౩౪౫౬౭౮౯";
    String engChinesStr = "ABC導字會";


    Pattern ALPHANUMERIC_AND_SPACE_PATTERN_TELUGU = Pattern
            .compile("[a-zA-Z0-9 \\u0c00-\\u0c7f]*+");
    System.out.println(ALPHANUMERIC_AND_SPACE_PATTERN_TELUGU.matcher(vowels)
            .matches());


    Pattern ALPHANUMERIC_AND_SPACE_PATTERN_CHINESE = Pattern
            .compile("[a-zA-Z0-9 \\u4e00-\\u9fff]*+");

    Pattern ENGLISH_ALPHANUMERIC_SPACE_AND_NLS_PATTERN = Pattern
            .compile("[a-zA-Z0-9 \\u0080-\\u9fff]*+");

    System.out.println(ENGLISH_ALPHANUMERIC_SPACE_AND_NLS_PATTERN.matcher(engChinesStr)
            .matches());
Venkateswara Rao
quelle
3
  • Die Java-API für reguläre Ausdrücke funktioniert für den charTyp
  • Der charTyp ist implizit UTF-16
  • Wenn Sie UTF-8-Daten haben, müssen Sie diese bei der Eingabe in UTF-16 umcodieren, falls dies noch nicht geschehen ist

Unicode ist der universelle Satz von Zeichen, und UTF-8 kann alles beschreiben (einschließlich Steuerzeichen, Interpunktion, Symbole, Buchstaben usw.). Sie müssen genauer angeben, was Sie einschließen und was Sie ausschließen möchten. Reguläre Java-Ausdrücke verwenden die \p{category}Syntax, um Codepunkte nach Kategorie abzugleichen . Siehe den Unicode - Standard für die Liste der Kategorien.

Wenn Sie Wörter in einer Folge von Ideogrammen identifizieren und trennen möchten, müssen Sie sich eine komplexere API ansehen. Ich würde mit dem BreakIteratorTyp beginnen.

McDowell
quelle