¿Cómo hacer coincidir “algo hasta esta secuencia de caracteres” en una expresión regular?

Tome esta expresión regular: /^[^abc]/ . Esto coincidirá con cualquier carácter individual al comienzo de una cadena, excepto a, b, o c.

Si agrega un * después de él – /^[^abc]*/ – la expresión regular continuará agregando cada carácter subsiguiente al resultado, hasta que se encuentre con un a , o b , o c .

Por ejemplo, con la cadena fuente "qwerty qwerty whatever abc hello" , la expresión coincidirá con "qwerty qwerty wh" .

Pero, ¿y si quisiera que la cadena coincidente fuera "qwerty qwerty whatever "

… En otras palabras, ¿cómo puedo unir todo hasta (pero sin incluir) la secuencia exacta "abc" ?

No especificó qué sabor de expresión regular está utilizando, pero esto funcionará en cualquiera de los más populares que se pueden considerar “completos”.

 /.+?(?=abc)/ 

Cómo funciona

El .+? parte es la versión no codiciosa de .+ (uno o más de algo). Cuando usamos .+ , El motor básicamente coincidirá con todo. Entonces, si hay algo más en la expresión regular, retrocederá en pasos tratando de hacer coincidir la siguiente parte. Este es el comportamiento codicioso , que significa tanto como sea posible para satisfacer .

Cuando usas .+? , en lugar de emparejar todo de una vez y volver para otras condiciones (si las hay), el motor coincidirá con los siguientes caracteres por pasos hasta que coincida la siguiente parte de la expresión regular (de nuevo, si corresponde). Este es el no codicioso , es decir, coincide con el menor número posible de satisfacer .

 /.+X/ ~ "abcXabcXabcX" /.+/ ~ "abcXabcXabcX" ^^^^^^^^^^^^ ^^^^^^^^^^^^ /.+?X/ ~ "abcXabcXabcX" /.+?/ ~ "abcXabcXabcX" ^^^^ ^ 

A continuación tenemos (?= {contents} ) , una aserción de ancho cero , una mirada alrededor . Esta construcción agrupada coincide con su contenido, pero no cuenta como caracteres coincidentes ( ancho cero ). Solo regresa si es una coincidencia o no ( aserción ).

Por lo tanto, en otros términos, la expresión regular /.+?(?=abc)/ significa:

Haga coincidir los caracteres lo menos posible hasta encontrar un “abc”, sin contar el “abc”.

Si está buscando capturar todo hasta “abc”:

 /^(.*?)abc/ 

Explicación:

( ) captura la expresión dentro de los paréntesis para acceder usando $1 , $2 , etc.

^ partido comienzo de línea

.* coincide con cualquier cosa ? no codicioso (coincide con el mínimo de caracteres requeridos) – [1]

[1] La razón por la que esto es necesario es que, de lo contrario, en la siguiente cadena:

 whatever whatever something abc something abc 

de forma predeterminada, las expresiones regulares son codiciosas , lo que significa que coincidirá tanto como sea posible. Por /^.*abc/ tanto, /^.*abc/ coincidiría con “lo que sea que algo sea algo abc”. ¿Agregar el cuantificador no codicioso ? hace que la expresión regular solo coincida con “lo que sea que sea algo”.

Como señalaron @Jared Ng y @Issun, la clave para resolver este tipo de RegEx es como “emparejar todo hasta una determinada palabra o subcadena” o “emparejar todo después de una determinada palabra o subcadena”. Se denomina aserciones de “longitud aproximada” de longitud cero. . Lee más sobre ellos aquí.

En su caso particular, puede ser resuelto con una mirada positiva hacia adelante. Una imagen vale mas que mil palabras. Ver la explicación detallada en la captura de pantalla.

Regex101 Captura de pantalla

Lo que necesitas es buscar una afirmación como .+? (?=abc) .+? (?=abc) .

Ver: Aserciones de longitud cero y mirar hacia adelante

Tenga en cuenta que [abc] no es lo mismo que abc . Dentro de los corchetes no es una cadena, cada personaje es solo una de las posibilidades. Fuera de los corchetes se convierte en la cuerda.

Esto tendrá sentido con la expresión regular.

  1. La palabra exacta se puede obtener del siguiente comando de expresión regular:

(“(.*?)”)/gramo

Aquí, podemos obtener la palabra exacta a nivel mundial que pertenece dentro de las comillas dobles. Por ejemplo, si nuestro texto de búsqueda es,

Este es el ejemplo de las palabras “doble cita”

entonces obtendremos “doble cotización” de esa oración.

Para expresiones regulares en Java, y creo que también en la mayoría de los motores de expresiones regulares, si desea incluir la última parte, esto funcionará:

 .+?(abc) 

Por ejemplo, en esta línea:

 I have this very nice senabctence 

selecciona todos los caracteres hasta “abc” y también incluye abc

usando nuestra expresión regular, el resultado será: I have this very nice senabc

Pruebe esto: https://regex101.com/r/mX51ru/1

Creo que necesitas subexpresiones. Si recuerdo bien, puede usar los corchetes normales () para subexpresiones.

Esta parte es del manual grep:

  Back References and Subexpressions The back-reference \n, where n is a single digit, matches the substring previously matched by the nth parenthesized subexpression of the regular expression. 

Haga algo como ^[^(abc)] debería hacer el truco.

El $ marca el final de una cadena, por lo que algo como esto debería funcionar: [[^abc]*]$ donde estás buscando algo que NO TERMINA en cualquier iteración de abc , pero tendría que ser al final

Además, si está utilizando un lenguaje de scripting con expresiones regulares (como php o js), tienen una función de búsqueda que se detiene cuando se encuentra con un patrón (y puede especificar comenzar desde la izquierda o comenzar desde la derecha, o con php, puedes hacer una implosión para duplicar la cadena).

prueba esto

 .+?efg 

Consulta :

 select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual; 

salida:

 hijklmn