2009-06-02 8 views
49

Tengo un motor de plantillas de python que usa mucho la expresión regular. Se utiliza como concatenación:Sintaxis de expresiones regulares para "hacer coincidir nada"?

re.compile(regexp1 + "|" + regexp2 + "*|" + regexp3 + "+") 

puedo modificar subseries individuales (regexp1, regexp2 etc).

¿Hay alguna expresión pequeña y ligera que no coincida con nada, que puedo usar dentro de una plantilla donde no quiero ninguna coincidencia? Lamentablemente, a veces '+' o '*' se anexa al átomo de expresión regular, por lo que no puedo usar una cadena vacía; se producirá un error de "no repetir nada".

+1

http://stackoverflow.com/questions/1723182/a-regex-that-will-never-be-matched-by-anything –

Respuesta

76

Esto no debe coincidir con cualquier cosa:

re.compile('$^') 

Así que si se reemplaza regexp1, regexp2 y regexp3 con '$ ^' que será imposible encontrar una coincidencia. A menos que esté utilizando el modo multilínea.


Después de algunas pruebas he encontrado una solución mejor

re.compile('a^') 

Es imposible igualar y fallará antes que la solución anterior. Puede reemplazar a con cualquier otro personaje y siempre será imposible hacer coincidir

+0

¿Eso no coincidirá con nada y es liviano para que el motor regexp lo procese? (No quiero que mis expresiones regulares de trozo coman mucha CPU) – grigoryvp

+0

@Eye of hell. Debería ser liviano. Esto intentará hacer coincidir un final de línea seguido de un inicio de línea. Lo cual es imposible en una línea. –

+1

Pero es posible con múltiples líneas de curso (dependiendo de si el indicador está habilitado) - para una solución que funciona si el indicador está habilitado o no, consulte mi respuesta. –

2

¿Quizás '.{0}'?

+0

Devolverá un objeto coincidente – grigoryvp

3
"()" 

coincide nada y nada solamente.

+0

Coincidirá con una cadena vacía. Depende de lo que @Eye of Hell esté solicitando. Si no quiere ninguna coincidencia, no funcionará. –

+3

No, esto coincide con cualquier cosa, pero se considera un mal patrón en muchas implementaciones de expresiones regulares (dependiendo de las banderas a veces) – ShuggyCoUk

+0

No desea que coincida nada. Comprobaré cómo Python interpreta "()". – grigoryvp

15

para que coincida con una cadena vacía - incluso en modo multi - se puede utilizar \A\Z, por lo que:

re.compile('\A\Z|\A\Z*|\A\Z+') 

La diferencia es que \A y \Z son de inicio y final de cadena, mientras ^ y $ éstos puede coincidir con el inicio/fin de líneas, por lo que $^|$^*|$^+ podría coincidir con una cadena que contenga líneas nuevas (si la marca está activada).

Y para no coincidir en nada (ni siquiera una cadena vacía), sólo tiene que tratar de encontrar el contenido antes del inicio de la cadena, por ejemplo:

re.compile('.\A|.\A*|.\A+') 

Dado que no hay caracteres pueden venir antes de \ A (por definición) , esto siempre no coincidirá.

+0

La tuya se ve mejor que la mía, ya que supongo que saldrá más rápido que al final de la línea. – ShuggyCoUk

+0

Peter, utilizas \ z (minúsculas) mientras mi guía de bolsillo Python me dice que la aserción del final de la cadena es \ Z (mayúsculas)? – ThomasH

+0

ThomasH, ambos son finales de cadena, pero la versión en mayúsculas permite una línea nueva al final, mientras que la letra minúscula no. –

1

Usted podría utilizar
\z..
Este es el final absoluto de la cadena, seguido por dos de nada

Si + o * se insertan en el extremo este sigue funcionando negarse a coincidir con nada

0

O , use una lista de comprensión para eliminar las entradas de expresiones regulares inútiles y únete para unirlas.Algo así como:

re.compile('|'.join([x for x in [regexp1, regexp2, ...] if x != None])) 

asegúrese de agregar algunos comentarios al lado de esa línea de código, aunque :-)

23

(?!) siempre debe dejar de igualar. Es el aspecto negativo de ancho cero anticipado. Si lo que está entre paréntesis coincide, la coincidencia completa falla. Dado que no tiene nada, fallará el partido por cualquier cosa (incluso nada).

+3

Derecho, yo también iba a publicar esto también. Esta es la mejor manera, si su lenguaje es compatible con lookaheads. (? =) coincide con cada cadena. –

Cuestiones relacionadas