2011-12-22 43 views
7

Tengo una expresión regular que quiero anular, p. Ej.cómo negar cualquier expresión regular en Java

/(.{0,4}) 

que devuelve la siguiente String.matches

"/1234" true 
"/12" true 
"/" true 
"" false 
"1234" false 
"/12345" false 

¿Hay una manera de negar (usando regx solamente) a la anterior para que los resultados son los siguientes:

"/1234" false 
"/12" false 
"/" false 
"" true 
"1234" true 
"/12345" true 

I' Estoy buscando una solución general que funcione para cualquier regx sin volver a escribir toda la expresión regular.

He observado el siguiente How to negate the whole regex? usando (?! Patrón), pero eso no parece funcionar para mí.

La siguiente regx

(?!/(.{0,4})) 

devuelve lo siguiente:

"/1234" false 
"/12" false 
"/" false 
"" true 
"1234" false 
"/12345" false 

que no es lo que quiero. Cualquier ayuda sería apreciada.

+4

¿No podría coincidir y negar si coincide o no? Esa es la solución de uso general para cualquier expresión regular sin reescribir la expresión regular. –

+2

Esta codificación coincidente es parte de un marco existente que no se puede cambiar sin romper otras cosas. – Wayne

Respuesta

22

Es necesario agregar anclas. La expresión regular originales (menos los paréntesis innecesarios):

/.{0,4} 

... coincide con una cadena que contiene una barra seguida de cero a cuatro caracteres más. Pero, debido a que está utilizando el método matches() que está anclado de forma automática, como si fuera verdad:

^/.{0,4}$ 

Para lograr lo contrario de eso, no se puede confiar en el anclaje automático; tienes que hacer que al menos el ancla final sea explícita dentro de la búsqueda anticipada. También hay que "rellenar" la expresión regular con una .* porque matches() requiere la expresión regular para consumir toda la cadena:

(?!/.{0,4}$).* 

pero recomiendo que se ancla de manera explícita toda la expresión regular, así:

^(?!/.{0,4}$).*$ 

No hace daño, y hace que tu intención quede perfectamente clara, especialmente para las personas que aprendieron expresiones regulares de otros sabores como Perl o JavaScript. El anclaje automático del método matches() es altamente inusual.

+0

¿Esto funcionará para cualquier expresión regular? es decir '' String negateRegex (String regex) {return "(?!" + regex + "$). *"; } '¿funcionaría como se esperaba? ¿Puede esto negarse a sí mismo? es decir, 'negateRegex (negateRegex (regex))' sería funcionalmente el mismo que 'regex'? – Mark

+0

Hmm, he hecho algunas pruebas preliminares aquí [1] y parece estar funcionando en todos los casos que he intentado, incluida la negación de una negación. [1] http://www.regexplanet.com/advanced/java/index.html – Mark

+0

No creo que puedas manipular regex como una cadena. ¿Consideras \ Q y \ E? ¿Consideras la barra invertida al final? – ntysdd

Cuestiones relacionadas