La forma explícita de decir "buscar hasta X
pero sin incluir X
" es:
(?:(?!X).)*
donde X
puede ser cualquier expresión regular.
Sin embargo, en su caso, esto podría ser excesivo; aquí la forma más fácil sería
[^z]*
Esto coincidirá con cualquier cosa excepto z
y, por lo tanto, se detendrá justo antes del siguiente z
.
Así .*?quick[^z]*
coincidirá The quick fox jumps over the la
.
Sin embargo, tan pronto como tenga más de una letra simple a la que prestar atención, (?:(?!X).)*
entra en juego, por ejemplo
(?:(?!lazy).)*
- coincidir con cualquier cosa hasta el comienzo de la palabra lazy
.
Esto está utilizando una afirmación de anticipación , más específicamente una anticipación negativa.
.*?quick(?:(?!lazy).)*
coincidirá The quick fox jumps over the
.
Explicación:
(?:
(?!lazy)
.
)*
Además, al buscar palabras clave, es posible que desee rodearlas con anclajes de límites de palabras: \bfox\b
solo coincidirá con la palabra completa, fox
pero no con el zorro foxy
.
Nota
Si el texto que se va a hacer coincidir también puede incluir saltos de línea, deberá establecer la opción "el punto coincide con todo" de su motor de expresiones regulares. Por lo general, puede lograrlo anteponiendo (?s)
la expresión regular, pero eso no funciona en todos los motores de expresiones regulares (especialmente JavaScript).
Solución alternativa:
En muchos casos, también puede usar una solución más simple y legible que usa un cuantificador diferido. Al agregar un ?
al *
cuantificador, intentará hacer coincidir la menor cantidad de caracteres posible desde la posición actual:
.*?(?=(?:X)|$)
coincidirá con cualquier número de caracteres, deteniéndose justo antes X
(que puede ser cualquier expresión regular) o al final de la cadena (si X
no coincide). Es posible que también deba configurar la opción "el punto coincide con todo" para que esto funcione. (Nota: agregué un grupo que no captura X
para aislarlo de manera confiable de la alternancia)
grep
, pero esta respuesta sí.