2011-11-22 12 views
5

Me gustaría utilizar un tipo de operador lógico "Y" en mi expresión regular. yo probamos este:Operador lógico Y con la expresión regular de php

(?=exp1)(?=exp2) 

Pero en PHP ?= no funciona y la necesidad de escribir mi programa en lenguaje PHP. ¿Hay otro método? La expresión tiene que coincidir si están presentes todas las condiciones y en cualquier orden. No quiero escribir todas las permutaciones como:

(exp1)(exp2)(exp3)|(exp1)(exp3)(exp2)|.... 
+0

Creo que deberás dividir las expresiones regulares – DiogoDoreto

+4

Ummm. php soporta '(? = ...)': http://php.net/manual/en/regexp.reference.assertions.php –

Respuesta

9

PHP es compatible con las expresiones de búsqueda hacia delante. Sin embargo, probablemente no los estás usando correctamente.

Suponiendo que desea hacer coincidir una cadena que contiene los tres foo, bar y baz, necesita la expresión regular

^(?=.*foo)(?=.*bar)(?=.*baz) 

Esto devolverá a la altura de las cuerdas foobarbaz o barbazfoo etc. Sin embargo, que los partidos será la cadena vacía (porque los lookaheads no consumen ningún carácter). Si desea que la expresión regular para volver la propia cadena, utilice

^(?=.*foo)(?=.*bar)(?=.*baz).* 

que a su vez coincide con la cadena entera si cumple los tres criterios.

Me basta con utilizar

if (preg_match('/^(?=.*foo)(?=.*bar)(?=.*baz)/s', $subject)) { 
    # Successful match 
} else { 
    # Match attempt failed 
} 

tomar en cuenta que esto también coincidirá con una cadena como foonly bartender bazooka. Si no desea que (sólo permite permutaciones puros de uno por cada uno de los tres expresiones), puede hacerlo con un pequeño truco:

^(?:foo()|bar()|baz()){3}\1\2\3$ 

partidos foobarbaz, foobazbar, barfoobaz, barbazfoo, bazfoobar y bazbarfoo (y nada más). El "truco" está inspirado en el excelente libro de Jan Goyvaerts y Steven Levithan "Regular Expressions Cookbook" (página 304). Funciona como sigue:

  • Cada parte requerida (foo etc.) es seguido por un grupo de captura vacío () que siempre coincide si la parte requerida ha sido igualada.
  • De modo que si las tres partes requeridas coinciden, los tres grupos de captura vacíos coinciden.
  • Las siguientes referencias solo tienen éxito si cada uno de los grupos de captura ha participado en la coincidencia.
  • Así que si la cadena es foobarbar, la parte (?:foo()|bar()|baz()){3} se han emparejado, pero \3 falla, por lo que no cumple con la expresión regular en general.
  • Si, sin embargo, los tres tomaron parte en la coincidencia, \1\2\3 logra coincidir al final de la cadena porque cada uno de los grupos de captura no contiene nada más que la cadena vacía.
+0

Bueno, respuesta completa. +1 – FailedDev

+0

@tim ¿podría proporcionar recursos o información adicional sobre esto? Nunca he visto algo como foo() | bar() | baz() antes. – bozdoz

+0

Supongo que lo que estoy preguntando es ¿cuál es el significado de los corchetes vacíos? – bozdoz

1

Además de la respuesta de Tim @:

(?=exp1)(?=exp2) 

Esto nunca puede ser verdad.Dices en inglés sencillo: asegúrate de que el texto seguido aquí sea exp1 y también asegúrate de que el texto que se sigue aquí sea exp2. De ninguna manera esto es verdad. Nunca coincidirá.

Cuestiones relacionadas