Expresiones regulares: ¿Hay un operador AND?

Obviamente, puedes usar el | (¿pipa?) para representar OR , pero ¿hay alguna manera de representar AND también?

Específicamente, me gustaría hacer corresponder párrafos de texto que contengan TODA una determinada frase, pero sin ningún orden en particular.

Use una expresión regular que no consum.

La notación típica (es decir, Perl / Java) es:

(?= expr )

Esto significa “coincidencia expr, pero después de eso, continúe emparejándose en el punto de coincidencia original”.

Puedes hacer tantas como quieras, y esto será un “y”. Ejemplo:

(?=match this expression)(?=match this too)(?=oh, and this)

Incluso puede agregar grupos de captura dentro de las expresiones no consumidoras si necesita guardar algunos de los datos que contiene.

Debe usar la búsqueda anticipada, como han dicho algunos de los que respondieron, pero la búsqueda anticipada tiene que dar cuenta de otros caracteres entre su palabra de destino y la posición de coincidencia actual. Por ejemplo:

 (?=.*word1)(?=.*word2)(?=.*word3) 

El .* En el primer vistazo le permite unir todos los caracteres que necesite antes de que llegue a “word1”. Luego, la posición del partido se restablece y el segundo bash anticipado busca “palabra2”. Restablecer de nuevo, y la parte final coincide con “word3”; ya que es la última palabra que está revisando, no es necesario que esté a la vista, pero no duele.

Para hacer coincidir un párrafo completo, debe anclar la expresión regular en ambos extremos y agregar una .* Final para consumir los caracteres restantes. Usando la notación estilo Perl, eso sería:

 /^(?=.*word1)(?=.*word2)(?=.*word3).*$/m 

El modificador ‘m’ es para el modo multilínea; permite que ^ y $ coincidan en los límites de los párrafos (“límites de línea” en el uso de expresiones regulares). En este caso, es esencial que no utilice el modificador ‘s’, que permite que el metacarácter de punto coincida con los saltos de línea, así como con todos los demás caracteres.

Finalmente, quiere asegurarse de que está combinando palabras completas y no solo fragmentos de palabras más largas, por lo que debe agregar límites de palabras:

 /^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$/m 

Mira este ejemplo:

Tenemos 2 expresiones regulares A y B y queremos unirlas a ambas, por lo que en el pseudo-código se ve así:

 pattern = "/A AND B/" 

Se puede escribir sin usar el operador AND de esta manera:

 pattern = "/NOT (NOT A OR NOT B)/" 

en PCRE:

 "/^(^A|^B)/" regexp_match(pattern,data) 

Puedes hacer eso con una expresión regular, pero probablemente quieras algo más. Por ejemplo, use varios regexp y combínelos en una cláusula if.

Puede enumerar todas las permutaciones posibles con una expresión regular estándar, como esta (coincide con a, byc en cualquier orden):

 (abc)|(bca)|(acb)|(bac)|(cab)|(cba) 

Sin embargo, esto hace una expresión regular muy larga y probablemente ineficiente, si tiene más de dos términos.

Si está utilizando alguna versión extendida de expresiones regulares, como la de Perl o Java, tienen mejores formas de hacerlo. Otras respuestas han sugerido usar la operación de búsqueda anticipada positiva.

El operador AND está implícito en la syntax RegExp.
En su lugar, el operador OR debe especificarse con una tubería.
El siguiente RegExp:

 var re = /ab/; 

significa la letra aY la letra b .
También funciona con grupos:

 var re = /(co)(de)/; 

significa el grupo co Y el grupo de .
Reemplazar el AND (implícito) con un OR requeriría las siguientes líneas:

 var re = /a|b/; var re = /(co)|(de)/; 

¿Por qué no usar awk?
con awk regex AND, OR matters es tan simple

 awk '/WORD1/ && /WORD2/ && /WORD3/' myfile 

¿No es posible en su caso hacer AND en varios resultados coincidentes? en pseudocódigo

 regexp_match(pattern1, data) && regexp_match(pattern2, data) && ... 

Si usas expresiones regulares de Perl, puedes usar el lookahead positivo:

Por ejemplo

 (?=[1-9][0-9]{2})[0-9]*[05]\b 

serían números mayores que 100 y divisibles por 5

Puede canalizar su salida a otra expresión regular. Usando grep, podrías hacer esto:

grep A | grep B

Además de la respuesta aceptada

Les proporcionaré algunos ejemplos prácticos que harán las cosas más claras para algunos de Ustedes. Por ejemplo, digamos que tenemos esas tres líneas de texto:

 [12/Oct/2015:00:37:29 +0200] // only this + will get selected [12/Oct/2015:00:37:x9 +0200] [12/Oct/2015:00:37:29 +020x] 

Vea la demostración aquí DEMO

Lo que queremos hacer aquí es seleccionar el signo +, pero solo si está después de dos números con un espacio y si es anterior a cuatro números. Esas son las únicas limitaciones. Utilizaríamos esta expresión regular para lograrlo:

 '~(?<=\d{2} )\+(?=\d{4})~g' 

Tenga en cuenta que si separa la expresión, obtendrá diferentes resultados.

O tal vez quieras seleccionar texto entre tags ... ¡pero no las tags! Entonces podrías usar:

 '~(?<=

).*?(?=<\/p>)~g'

para este texto:

 

Hello !

I wont select tags! Only text with in

Vea la demostración aquí DEMO

Use AND fuera de la expresión regular. En PHP, el operador de lookahead no parecía funcionar para mí, en cambio usé esto

 if( preg_match("/^.{3,}$/",$pass1) && !preg_match("/\s{1}/",$pass1)) return true; else return false; 

La expresión regular anterior coincidirá si la longitud de la contraseña es de 3 caracteres o más y no hay espacios en la contraseña.

El orden siempre está implícito en la estructura de la expresión regular. Para lograr lo que desea, tendrá que hacer coincidir la cadena de entrada varias veces con las diferentes expresiones.

Lo que quieres hacer no es posible con una sola expresión regular.

    Intereting Posts