Pregunta 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.


527
2018-01-22 16:49


origen


Respuestas:


Use una expresión regular que no consuma.

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

(?=expr)

Esto significa "coincidencia" expr pero después de eso, continúe emparejando en el punto de partido 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.


310
2018-01-22 16:58



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)

los .* en el primer vistazo, permite que coincida con todos los caracteres que necesita antes de que llegue a "word1". Luego, la posición del partido se restablece y el segundo intento 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 un 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; deja el ^ y $ coincidir en los límites de los párrafos ("límites de línea" en la expresión regular). Es esencial en este caso que no use el modificador 's', que permite que el metacarácter de punto coincida con las líneas nuevas 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

270
2018-01-22 20:04



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)

27
2018-04-20 12:11



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.


22
2018-01-22 18:07



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

var re = /ab/;

significa la letra a  Y la carta 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)/;

11
2018-06-30 11:25



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

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

9
2017-12-27 13:49



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

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

8
2018-01-22 16:57