validate test regulares regular probar online expresiones expresion espacio ejemplos blanco alfanumerico regex

regex - test - Reemplace patrones que están dentro de delimitadores usando una llamada de expresión regular



regex replace online (5)

Necesito recortar todas las ocurrencias del patrón ''-'' que están dentro de comillas simples en cadena larga (dejando intactos los que están fuera de las comillas simples).

¿Hay una forma de expresión regular de hacer esto? (Usarlo con un iterador del idioma es ACEPTABLE).

Por ejemplo, empezando por

"xxxx rt / $ ''dfdf--fggh-dfgdfg'' ghgh- dddd -- ''dfdf'' ghh-g ''--ggh--'' vcbcvb"

Debería terminar con:

"xxxx rt / $ ''dfdffggh-dfgdfg'' ghgh- dddd -- ''dfdf'' ghh-g ''ggh'' vcbcvb"

Así que estoy buscando una expresión regular que pueda ejecutarse desde los siguientes idiomas, como se muestra

  • JavaScript input.replace (/ someregex / g, "")
  • PHP preg_replace (''/ someregex /'', "", entrada)
  • Python re.sub (r''someregex '', "", entrada)
  • Ruby input.gsub (/ someregex /, "")

Esto no se puede hacer con expresiones regulares, porque necesita mantener el estado de si está dentro de comillas simples o fuera, y regex es inherentemente sin estado. (Además, por lo que yo entiendo, se pueden escapar las comillas simples sin terminar la región "interior").

Su mejor opción es iterar a través de la cadena carácter por carácter, manteniendo una bandera booleana en si está dentro de una región citada y elimine la de esa manera.


Hm. Puede haber una forma en Python si no hay apóstrofos entre comillas, dado que existe el constructo (?( Id / name ) yes-pattern | no-pattern ) en las expresiones regulares, pero ahora va más allá de mi cabeza.

¿Esto ayuda?

def remove_double_dashes_in_apostrophes(text): return "''".join( part.replace("--", "") if (ix&1) else part for ix, part in enumerate(text.split("''")))

Parece funcionar para mi. Lo que hace, es dividir el texto de entrada en partes en apóstrofes, y reemplazar el "-" solo cuando la parte tiene un número impar (es decir, ha habido un número impar de apóstrofes antes de la parte). Nota sobre "número impar": la numeración de las piezas comienza desde cero.


Puede usar el siguiente script sed, creo:

:again s/''/(.*/)--/(.*/)''/''/1/2''/g t again

Almacene eso en un archivo (rmdashdash.sed) y haga cualquier magia exec en su lenguaje de scripting que le permita hacer el siguiente equivalente de shell:

sed -f rmdotdot.sed < archivo que contiene sus datos de entrada

Lo que hace el script es:

:again <- solo una etiqueta

s/''/(.*/)--/(.*/)''/''/1/2''/g

sustituto, por el patrón ''seguido de cualquier cosa seguida de - seguida de cualquier cosa seguida de'', solo las dos cosas dentro de las comillas.

t again <- alimentar de nuevo la cadena resultante a sed.

Tenga en cuenta que este script convertirá ''----'' en '''', ya que es una secuencia de dos - entre comillas. Sin embargo, ''---'' se convertirá en ''-''.

No es una escuela como la vieja escuela.


Si doblar las reglas un poco está permitido, esto podría funcionar:

import re p = re.compile(r"((?:^[^'']*'')?[^'']*?(?:''[^'']*''[^'']*?)*?)(-{2,})") txt = "xxxx rt / $ ''dfdf--fggh-dfgdfg'' ghgh- dddd -- ''dfdf'' ghh-g ''--ggh--'' vcbcvb" print re.sub(p, r''/1-'', txt)

Salida:

xxxx rt / $ ''dfdf-fggh-dfgdfg'' ghgh- dddd -- ''dfdf'' ghh-g ''-ggh-'' vcbcvb

La expresión regular:

( # Group 1 (?:^[^'']*'')? # Start of string, up till the first single quote [^'']*? # Inside the single quotes, as few characters as possible (?: ''[^'']*'' # No double dashes inside theses single quotes, jump to the next. [^'']*? )*? # as few as possible ) (-{2,}) # The dashes themselves (Group 2)

Si hubiera diferentes delimitadores para el inicio y el final, podría usar algo como esto:

-{2,}(?=[^''`]*`)

Editar: Me di cuenta de que si la cadena no contiene ninguna comilla, coincidirá con todos los guiones dobles en la cadena. Una forma de solucionarlo sería cambiar

(?:^[^'']*'')?

al principio para

(?:^[^'']*''|(?!^))

Regex actualizada:

((?:^[^'']*''|(?!^))[^'']*?(?:''[^'']*''[^'']*?)*?)(-{2,})


Encontré otra manera de hacerlo a partir de una respuesta de Greg Hewgill en Qn138522
Se basa en el uso de esta expresión regular (adaptada para contener el patrón que estaba buscando):

--(?=[^/']*''([^'']|''[^'']*'')*$)

Greg explica:

"Lo que hace es usar la coincidencia que no captura (?=...) para verificar que el carácter x se encuentre dentro de una cadena entre comillas. Busca algunos caracteres que no sean las citas hasta la siguiente cita, luego busca una secuencia de cualquiera de los dos. caracteres o grupos de caracteres citados, hasta el final de la cadena. Esto se basa en su suposición de que las comillas siempre están balanceadas. Esto tampoco es muy eficiente ".

Los ejemplos de uso serían:

  • JavaScript: input.replace(/--(?=[^'']*''([^'']|''[^'']*'')*$)/g, "")
  • PHP: preg_replace(''/--(?=[^/']*''([^'']|''[^'']*'')*$)/'', "", input)
  • Python: re.sub(r''--(?=[^/']*''([^'']|''[^'']*'')*$)'', "", input)
  • Ruby: input.gsub(/--(?=[^/']*''([^'']|''[^'']*'')*$)/, "")

He probado esto para Ruby y proporciona el resultado deseado.