¿Java regex para soportar Unicode?

80

Para hacer coincidir la A con la Z, usaremos expresiones regulares:

[A-Za-z]

¿Cómo permitir que las expresiones regulares coincidan con los caracteres utf8 ingresados ​​por el usuario? Por ejemplo, palabras chinas como 环保 部

cometa
fuente
2
En Java 7, la expresión regular Unicode es compatible con UNICODE_CHARACTER_CLASSbandera o incrustable (?U). Ver stackoverflow.com/questions/4304928/…
Alastair McCormack

Respuestas:

120

Lo que busca son propiedades Unicode.

por ejemplo, \p{L}es cualquier tipo de letra de cualquier idioma

Entonces, una expresión regular que coincida con una palabra china podría ser algo como

\p{L}+

Hay muchas propiedades de este tipo, para obtener más detalles, consulte regular-expressions.info

Otra opción es usar el modificador

Pattern.UNICODE_CHARACTER_CLASS

En Java 7 hay una nueva propiedad Pattern.UNICODE_CHARACTER_CLASSque habilita la versión Unicode de las clases de caracteres predefinidas, vea mi respuesta aquí para obtener más detalles y enlaces

Podrías hacer algo como esto

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

y \wcoincidiría con todas las letras y todos los dígitos de cualquier idioma (y, por supuesto, algunas palabras que combinan caracteres como _).

stema
fuente
Para hacer coincidir palabras como Da̱nx̱a̱laga̱litła̱n, ¿necesitamos indicarle al comparador de patrones que combine los signos diacríticos?
Dave Jarvis
9

Para hacer coincidir caracteres individuales, simplemente puede incluirlos en una clase de carácter, ya sea como literales o mediante la \u03FBsintaxis.

Obviamente, a menudo no se pueden enumerar todos los caracteres permitidos en idiomas ideográficos. Para que la expresión regular trate los caracteres Unicode de acuerdo con su tipo o bloque de código, se admiten varios otros escapes que se definen aquí . Mire la sección "Soporte Unicode", particularmente las referencias a la Characterclase y al estándar Unicode en sí.

Kilian Foth
fuente
cómo combinar varios caracteres utf8 ingresados ​​por el ejemplo del usuario 环保 部, porque el usuario ingresará un número aleatorio de caracteres
cometa
1
Es como hacer coincidir múltiples caracteres latinos: [a-z]+o [a-z]{3}ni siquiera [a-z]{2,10}. Lo único diferente es lo que permite en la clase de caracteres a la que se aplica el cuantificador.
Kilian Foth
9

Para abordar el soporte de NLS y evitar aceptar caracteres especiales en inglés, podemos usar el siguiente patrón ...

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

Para referencia de punto de código UTF: http://www.utf8-chartable.de/unicode-utf8-table.pl

Fragmento de código:

    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
fuente
3
  • la API de expresión regular de Java funciona en el chartipo
  • el chartipo es implícitamente UTF-16
  • Si tiene datos UTF-8, deberá transcodificarlos a UTF-16 en la entrada si aún no lo ha hecho.

Unicode es el conjunto universal de caracteres y UTF-8 puede describirlo todo (incluidos los caracteres de control, la puntuación, los símbolos, las letras, etc.). Deberá ser más específico sobre lo que desea incluir y lo que desea excluir. Las expresiones regulares de Java utilizan la \p{category}sintaxis para hacer coincidir los puntos de código por categoría . Consulte el estándar Unicode para ver la lista de categorías.

Si desea identificar y separar palabras en una secuencia de ideogramas, deberá buscar una API más sofisticada. Empezaría por el BreakIteratortipo.

McDowell
fuente