Regex hasta pero no incluido

Para regex, ¿cuál es la syntax para buscar hasta pero no incluir? Más o menos como:

Haystack: The quick red fox jumped over the lazy brown dog Expression: .*?quick -> and then everything until it hits the letter "z" but do not include z 

La forma explícita de decir “buscar hasta X pero no incluir X ” es:

 (?:(?!X).)* 

donde X puede ser cualquier expresión regular.

En su caso, sin embargo, esto podría ser excesivo – aquí la manera más fácil sería

 [^z]* 

Esto coincidirá con cualquier cosa excepto z y, por lo tanto, se detendrá justo antes de la próxima z .

Entonces .*?quick[^z]* coincidirá The quick fox jumps over the la .

Sin embargo, tan pronto como tenga más de una letra simple para tener en cuenta, (?:(?!X).)* Entra en juego, por ejemplo

(?:(?!lazy).)* – Haga coincidir cualquier cosa hasta el comienzo de la palabra lazy .

Esto está usando 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:

 (?: # Match the following but do not capture it: (?!lazy) # (first assert that it's not possible to match "lazy" here . # then match any character )* # end of group, zero or more repetitions. 

Además, al buscar palabras clave, es posible que desee rodearlas con delimitadores de límite de palabras: \bfox\b solo coincidirá con la palabra completa fox pero no con el zorro en foxy .

Nota

Si el texto que se va a combinar también puede incluir saltos de línea, tendrá que establecer la opción “punto coincide con todos” de su motor de expresiones regulares. Por lo general, puede lograrlo anteponiendo (?s) a 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 más legible que utiliza un cuantificador perezoso. Al agregar un ? para el * 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 de 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 “dot matches all” para que esto funcione. (Nota: agregué un grupo que no capturó alrededor de X para aislarlo confiablemente de la alternancia)

Una syntax de regex anticipada puede ayudarte a lograr tu objective. Por lo tanto, una expresión regular para su ejemplo es

 .*?quick.*?(?=z) 

Y es importante notar el .*? concordancia diferida antes del (?=z) búsqueda anticipada: la expresión coincide con una subcadena hasta una primera aparición de la letra z .

Aquí está la muestra del código C #:

 const string text = "The quick red fox jumped over the lazy brown dogz"; string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value; Console.WriteLine(lazy); // The quick red fox jumped over the la string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value; Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog 

Prueba esto

 (.*?quick.*?)z