Una expresión regular para excluir una palabra / cadena

299

Tengo una expresión regular de la siguiente manera:

^/[a-z0-9]+$

Esto coincide con cadenas como /helloo /hello123.

Sin embargo, me gustaría excluir un par de valores de cadena como /ignoremey /ignoreme2.

¡He probado algunas variantes pero parece que no funciona!

Mi último intento débil fue

^/(((?!ignoreme)|(?!ignoreme2))[a-z0-9])+$

Cualquier ayuda seria gratamente apreciada :-)

romiem
fuente
1
Posible duplicado: stackoverflow.com/questions/1395177/…
Anderson Green

Respuestas:

376

Aquí hay otra forma (usando una perspectiva negativa ):

^/(?!ignoreme|ignoreme2|ignoremeN)([a-z0-9]+)$ 

Nota: Sólo hay una expresión de captura: ([a-z0-9]+).

Seth
fuente
1
Brillante, eso parece haber hecho el truco. De hecho, necesito esta regla para la reescritura de URL y quería ignorar la carpeta "images", "css" y "js". Entonces, mi regla es la siguiente: ^ / (?! css | js | images) ([az] +) /? (\? (. +))? $ Y se reescribe en /Profile.aspx?id=$1&$3 ¿Esta regla funcionará correctamente y también propagará la cadena de consulta? Entonces, si alguien visita mydomain.com/hello?abc=123, me gustaría reescribirlo en mydomain.com/Profile.aspx?id=hello&abc=123 También estoy un poco inseguro sobre el rendimiento de (. +) En el final para capturar la cadena de consulta en la solicitud original.
romiem
Parece que esta es otra pregunta. Parece que la expresión regular que tiene capturará la cadena de consulta: pruebe y vea si aparece la cadena de consulta. Además, (\?(.+))?$debe ser rápido. No me preocuparía demasiado por la velocidad.
Seth
1
Esto no funcionó para mí, mientras que la solución de Alix Axel sí funcionó. Estoy usando la java.util.regex.Patternclase de Java .
Mark Jeronimus
1
Confirmo el reMark de Mark;), por ejemplo, Pycharm está basado en Java, ¿no? Entonces, teniendo en cuenta las expresiones regulares en la búsqueda de Pycharm, la solución de Alix funciona, la otra no.
fanny
43

Esto debería hacerlo:

^/\b([a-z0-9]+)\b(?<!ignoreme|ignoreme2|ignoreme3)

Puede agregar tantas palabras ignoradas como desee, aquí hay una implementación simple de PHP:

$ignoredWords = array('ignoreme', 'ignoreme2', 'ignoreme...');

preg_match('~^/\b([a-z0-9]+)\b(?<!' . implode('|', array_map('preg_quote', $ignoredWords)) . ')~i', $string);
Alix Axel
fuente
pensé que mirar hacia atrás requiere un patrón de ancho fijo?
Simon
2
@AlixAxel Sí, pero las bibliotecas de expresiones regulares más inteligentes permitirán una alternancia con diferentes longitudes para las alternativas (y usarán la más larga), siempre que cada alternativa sea de longitud fija.
ChrisF
Esto es inteligente, pero falla para mí si la palabra ignorada está al final de cualquier otra palabra. es decir, si agrega 'a' como una de las palabras ignoradas, entonces cualquier palabra que termine en a se ignora
singmotor
21

Como desea excluir ambas palabras, necesita una conjunción:

^/(?!ignoreme$)(?!ignoreme2$)[a-z0-9]+$

Ahora ambas condiciones deben ser verdaderas (no se permite ignoreme ni ignoreme2 ) para tener una coincidencia.

Gumbo
fuente
1
Esto es equivalente al más corto anterior que es un aspecto negativo de un conjunto de alternativas.
ChrisF
44
@ ChrisF No, en realidad no. La solución de Seth no coincidiría con algo como lo /ignoremenotque /sigue ignoreme.
Gumbo