2010-03-08 15 views
60

Sé que la siguiente expresión regular coincidirá con "rojo", "verde" o "azul".Coincidir todo excepto cadenas especificadas

red|green|blue 

¿Hay una manera sencilla de hacer que coincida con todo excepto varias cadenas especificadas?

+1

No todos los sabores de expresiones regulares pueden hacer esto. ¿En qué entorno estás trabajando? ¿Java? Perl? .¿RED? ¿Alguna biblioteca regex de C/C++? Un RDBMS? – FrustratedWithFormsDesigner

+5

No dice lo que quiere, pero podría simplemente invertir el sentido de la operación de "coincidencia". Esto no te ayudará si estás intentando hacer extracción en las partes que no coinciden, pero para probar si una cadena excluida no está presente funcionaría: 'if (! S.match (/ red | green | blue /)) ... 'Nota: Sé que el OP no especifica qué idioma/marco, por lo que lo anterior debe considerarse un ejemplo genérico, no preceptivo. – tvanfosson

Respuesta

28

depende del idioma, pero no son en general negativas-afirmaciones se puede poner en modo:

(?!red|green|blue) 

(Gracias por la corrección de la sintaxis, lo anterior es válido Java y Perl, tu caso es distinto)

+2

Quiere decir '(?! Rojo | verde | azul)'. –

+1

@caskey, la respuesta completa es una combinación de la mía y la tuya. Si desea unirlos, eliminaré el mío. –

+4

Esta respuesta sería mucho más útil si la explicaste un poco. Por ejemplo: ¿Qué significa "?" y "!" ¿media? ¿Por qué necesitas grupos de captura? – Lii

87

Si quiere asegurarse de que la cadena no sea roja, verde ni azul, la respuesta de caskey es esta. Sin embargo, lo que a menudo se desea es asegurarse de que la línea no contenga rojo, verde o azul en ninguna parte. Por eso, anclar la expresión regular con ^ e incluyen .* en la búsqueda negativa hacia delante:

^(?!.*(red|green|blue)) 

Además, suponga que desea líneas que contienen la palabra "motor", pero sin que ninguno de esos colores:

^(?!.*(red|green|blue)).*engine 

se podría pensar que se puede factorizar el .* a la cabeza de la expresión regular:

^.*(?!red|green|blue)engine  # Does not work 

pero se puede no. Debe tener ambas instancias de .* para que funcione.

+1

@Russ Gracias por señalar el error. He editado la respuesta. Lo arreglé con algunos paréntesis, pero tu solución con las copias adicionales de '. *' También es buena. Sin embargo, no estoy convencido de que sea necesario. –

+0

el final. * No es necesario si solo desea una verificación booleana para una coincidencia. Sin embargo, si realmente quiere el texto completo que lo necesita, lo necesita. Además ... tu nueva solución es agradable y limpia. ¡Gracias! – Russ

5

Tuve la misma pregunta, las soluciones propuestas estaban casi funcionando pero tenían algún problema. Al final, la expresión regular que utilicé es:

^(?!red|green|blue).* 

Lo probé en Javascript y .NET.

. * No debe colocarse dentro de la búsqueda negativa de esta manera:^(?!. * Rojo | verde | azul) o haría que el primer elemento se comporte diferente del resto (es decir, "otrored" no lo haría) ser emparejado mientras que "anothergreen" sería)

15

No necesita un lookahead negativo.No es ejemplo de trabajo:

/([\s\S]*?)(red|green|blue)/g 

Descripción:

  • [\s\S] - cualquier carácter
  • * - Partido de 0 a ilimitado desde el grupo anterior
  • ? - Partido lo menos posible
  • (red|green|blue) - coincide con una de estas palabras
  • g - patrón de repetición

Ejemplo:

redwhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredwhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredredgreenredgreenredgreenredgreenredgreenbluewhiteredbluewhiteredbluewhiteredbluewhiteredbluewhitered

será:

whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite

prueba que: regex101.com

Toma 1155 pasos, pero si alguien puede Improv e seré apreciado.

+1

Esta respuesta sería mejor si explicaras cómo funciona el patten. – Lii

+0

@Lii No sé qué se debe explicar en este patrón. Es regex básico. – hlcs

+4

Puede reducir drásticamente el conteo de pasos intercambiando [\ s \ S] por un punto. Estaba muy confundido por qué aparentemente cada otro ejemplo captura cada palabra individualmente. De esta forma hay pasos levemente más regex pero requiere mucho menos procesamiento posterior. – Zatronium

5

Coincidencia Cualquier cosa menos Dada Cuerdas

Si desea hacer coincidir la cadena completa en la que desea que coincida con todo, pero algunas cadenas que puede hacerlo de esta manera:

^(?!(red|green|blue)$).*$

Esto dice, inicio la coincidencia desde el comienzo de la cadena donde no puede comenzar y terminar con rojo, verde o azul y hacer coincidir cualquier otra cosa con el final de la cadena.

Puedes probarlo aquí: https://regex101.com/r/rMbYHz/2

Tenga en cuenta que esto sólo funciona con motores de expresiones regulares que soportan una negative lookahead.

Cuestiones relacionadas