2011-04-12 21 views
7

Me gustaría hacer coincidir todas las cadenas que contengan una palabra determinada. como: sin embargoexpresión regular que contiene palabras Unicode

String regex = (?:\P{L}|\W|^)(ベスパ)(?:\b|$) 

, la clase del patrón no se compila:

java.util.regex.PatternSyntaxException: Unmatched closing ')' near index 39 
(?:\P{L}|\W|^)((?:ベス|ベス|ヘズ)(?:パ)|パ)|ハ)゚)(?:\b|$) 

ya me puse unicode_case para compilar parámetro, no está seguro de lo que va mal aquí

final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE| Pattern.CANON_EQ); 

Gracias por ¡ayuda! :)

+1

El patrón en su mensaje de error * contiene * dos adicionales) - ¿está equivocado el mensaje de error o su publicación? – Erik

+1

** No debe ** utilizar '\ W',' \ w', '\ s',' \ d', '\ b',' \ p {alpha} ', ni ninguna de las otras clases de caracteres accesos directos en expresiones regulares de Java, porque la biblioteca de expresiones regulares de Java no cumple con los [requisitos formales de las expresiones regulares de Unicode] (http://unicode.org/reports/tr18/#Compatibility_Properties). Puede simular '\ w' con' [\ pL \ pM \ p {Nd} \ p {Nl} \ p {Pc}] 'y' \ W' con '[^ \ pL \ pM \ p {Nd} \ p {Nl} \ p {Pc}] 'si no te importan los Enclosed_Alphanumerics.O puede usar una biblioteca de expresiones regulares o un lenguaje que cumpla con el estándar Unicode. Eso significa llamar a la biblioteca de expresiones reumáticas de la ICU, o llamar a Perl's, etc. – tchrist

+0

¿Compiló con 'java -encoding UTF-8'? – tchrist

Respuesta

0
(?:\P{L}|\W|^)((?:ベス|ベス|ヘズ)(?:パ)|パ)|ハ)゚)(?:\b|$) 
(   )((   )( ) ) ) )( ) 

El patrón en su mensaje de error tiene dos extra ')'

+0

Sí, pero ¿por qué recibe ese mensaje de error? No hay paréntesis sin coincidencia en su expresión original. – aioobe

+0

Um, no. Ese '\ W' arruinará tu día. – tchrist

+0

@aioobe: Buena pregunta. No podemos saberlo porque no ha publicado el código exacto de Java que inicializa su variable 'String regex'. – tchrist

0

caracteres Unicode en las expresiones regulares es una tricky business.

Aquí es un párrafo de la documentación de Pattern:

soporte Unicode

Esta clase sigue Informe técnico de Unicode # 18: Unicode Directrices expresión regular, la ejecución de su segundo nivel de apoyo, aunque con una sintaxis concreta ligeramente diferente.

Las secuencias de escape Unicode como \u2014 en el código fuente de Java se procesan como se describe en? 3.3 de la Especificación del lenguaje Java. Tales secuencias de escape también son implementadas directamente por el analizador de expresiones regulares para que los escapes Unicode se puedan usar en expresiones que se leen desde archivos o desde el teclado. Por lo tanto, las cadenas "\u2014" y "\\u2014", aunque no son iguales, se compilan en el mismo patrón, que coincide con el carácter con el valor hexadecimal 0x2014.

Por lo tanto, ya que sabemos:

  • = \u3049
  • = \u30B9
  • = \u30D1

la forma correcta de escribir el patrón de lo que busca es:

String regex = "(?:\\P{L}|\\W|^)(\\u30d9\\u30B9\\u30D1)(?:\\b|$)"; 

Otras lecturas:

+0

No, lo siento, pero ese documento ** MENTIRAS **. Creo que sí. Java ni siquiera cumple con el Nivel 1, y mucho menos con el Nivel 2 como dice. He estado trabajando con las personas JDK7, y ahora entienden lo mal que se encuentra. No debe usar esas cosas. Honesto. Todas las cosas RL1.2a están reventadas en Java, proporciona solo 3 de las 11 propiedades requeridas para RL1.2; incluso hacer RL1.1 bien. Hay muchas cosas serias mal con eso. Ni siquiera se acerca a proporcionar soporte de Nivel 1. – tchrist

+0

Jajaja, no tienes * nada * mejor que hacer, que sentarte a esperar para que aparezca una pregunta de expresión regular de la que te puedes quejar? Apareces en casi todas las preguntas de expresiones regulares, explicando qué tan rotas son las expresiones regulares de Java. ¿Por qué no te quedas callado a menos que realmente sepas la respuesta? – aioobe

+1

Él * sabe * la respuesta. Más al punto, él sabe que cualquier respuesta que no mencione qué tan roto está el soporte de expresiones regulares de Java, es incorrecto. Y no solo se está quejando, muchas veces ha explicado cómo hacer coincidir correctamente Unicode con las clases de expresiones regulares de Java. Pero es mucha información y no se puede esperar que publique todo en todas las ocasiones. –

1

Desde el mensaje de error dado, lo que parece en nada a la expresión regular de cuerda mostrado, deduzco que la el patrón original era esencialmente el siguiente, del cual me he tomado la libertad de reformatear, agregar constantes simbólicas a, y prefacio con números de línea que podríamos inspeccionar y abordar con más facilidad.

(Todos los patrones no triviales deben siempre escribirse en (?x) modo -. A pesar de Java lucha contra usted aquí, aún debe hacerlo)

1  (?: \P{L} | \W | ^) 
    2  (
    3   (?: \N{KATAKANA LETTER BE} \N{KATAKANA LETTER SU} 
    4   | \N{KATAKANA LETTER BE} \N{KATAKANA LETTER SU} 
    5   | \N{KATAKANA LETTER HE} \N{KATAKANA LETTER ZU} 
    6  ) 
    7   (?: \N{KATAKANA LETTER PA}) 
    8  | 
    9    \N{KATAKANA LETTER PA} 
10 ) 
11 | 
12    \N{KATAKANA LETTER HA} 
13 ) 
14  \N{COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK} 
15 ) 
16  (?: \b | $) 

Las primeras y últimas líneas están equivocados, pero están equivocados en una forma semántica relacionada con las expresiones regulares rotas de Java. No son sintácticamente mal.

Como debería ser ahora evidente, el problema sintáctico es que los paréntesis cercanos en las líneas 13 y 15 son espurios: no tienen paréntesis abiertos correspondientes.

A pesar de la primera y la última línea, todavía estoy tratando de entender qué es lo que realmente está tratando de hacer aquí. ¿Por qué la duplicación de las líneas 3 y 4? Eso no hace nada útil. Y no veo razón para la agrupación en la línea 7.

¿La intención es permitir que la marca de combinación se aplique a alguna de las anteriores?

En cuanto a los errores en la primera y la última línea, ¿entiendo que un simple límite de palabras es todo lo que estás buscando? ¿Pretendes incluir esos personajes fronterizos como parte de tu pareja, o solo estás tratando de establecer límites? ¿Por qué estás diciendo que no es una carta o una palabra no?

Los caracteres de palabra do incluyen letras, ya sabe, al menos, según la especificación Unicode que hacen, incluso si Java lo hace incorrecto. Desgraciadamente, acabas de incluir un montón de letras debido a la falla de expresiones regulares de Java, así que tendremos que recodificar esto una vez que entiendo lo que realmente quieres.

Si solo usara algo que fuera realmente compatible con UTS # 18, funcionaría bien, pero como supongo que no (no oí ninguna mención de ICU), tendremos que arreglarlo a lo largo de las líneas Tengo previously outlined.

Un lookbehind para una palabra no escrita o el inicio de una cadena funcionaría para la primera, y una búsqueda anticipada de una palabra no o el final de la cadena funcionaría para la última. Eso es lo que \b es, por supuesto, supuestamente que se debe hacer frente a los caracteres de las palabras que tienes aquí, y podría funcionar de esa forma siempre que te mantengas alejado de tu partícula sin palabras.

Pero hasta que pueda ver más de la intención original, no creo que deba decir más.

0

El modo UNICODE_CHARACTER_CLASS también se puede activar a través de la expresión de la bandera incorporado (T?)

intento:

(?U)(?:\P{L}|\W|^)((?:ベス|ベス|ヘズ)(?:パ)|パ)|ハ)゚)(?:\b|$) 

Pero arreglar sus soportes primero como no sé lo que quiere dentro o fuera en el grupo del medio

Cuestiones relacionadas