Pregunta

¿Cómo se podría escribir una expresión regular que coincide con un patrón que puede contener comillas, pero si lo hace, debe tener a juego comillas al principio y al final?

"?(pattern)"?

no funcionará porque permitirá a los patrones que comienzan con una cita, pero no terminan con uno.

"(pattern)"|(pattern)

funcionará, pero es repetitivo. ¿Hay una mejor manera de hacerlo sin repetir el patrón?

¿Fue útil?

Solución

Se puede obtener una solución sin repetir, haciendo uso de referencias hacia atrás y condicionales :

/^(")?(pattern)(?(1)\1|)$/

Partidos:

  • patrón
  • "patrón"

No coincide:

  • "patrón
  • patrón "

Este patrón es algo complejo, sin embargo. Primero busca una cotización opcional, y lo pone en retrorreferencia 1 si uno se encuentra. Entonces se busca para su patrón. A continuación, utiliza la sintaxis condicional a decir "si retrorreferencia 1 se encuentra una vez más, coincide con él, de otro modo que coincida con nada". Todo el patrón es anclado (lo que significa que tiene que aparecer por sí mismo en una línea) de manera que no se capturarán cotizaciones sin igual (de lo contrario el pattern en pattern" coincidiría).

Tenga en cuenta que el apoyo a los condicionales varía según el motor y la más prolija, pero expresiones repetitivas serán más ampliamente compatibles (y probablemente más fácil de entender).


Actualización: Una versión mucho más simple de esta expresión regular sería /^(")?(pattern)\1$/, que no necesita un condicional. Cuando me estaba poniendo a prueba este principio, el probador que estaba usando me dio un falso negativo, lo que me llevó a descuento que (vaya!).

Voy a dejar la solución con el hasta condicional para la posteridad y el interés, pero esta es una versión más simple que es más probable que el trabajo en una variedad más amplia de motores (referencias hacia atrás son la única característica que se utiliza aquí lo que podría ser no soportado) .

Otros consejos

En función del idioma que está utilizando, usted debe ser capaz de utilizar referencias hacia atrás. Algo como esto, por ejemplo:

(["'])(pattern)\1|^(pattern)$

De esta manera, usted está requiriendo que, o bien no hay cotizaciones, o que el presupuesto mismo es utilizado en ambos extremos.

Esto debería funcionar con expresiones regulares recursiva (que necesita más tiempo para obtener la derecha). Mientras tanto: en Perl , se puede construir un auto-modificable expresiones regulares . Voy a dejar esto como un ejemplo académica; -)

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

Resultados:

"pattern" OK
pattern OK
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top