Expressions régulières: Y a-t-il un opérateur AND?

De toute évidence, vous pouvez utiliser le | (pipe?) pour représenter OR , mais y a-t-il un moyen de représenter AND aussi?

Plus précisément, je voudrais faire correspondre des paragraphes de texte contenant TOUS une phrase donnée, mais sans ordre particulier.

Utilisez une expression régulière non consommasortingce.

La notation typique (Perl / Java) est:

(?= expr )

Cela signifie “correspond à expr mais après cela continue à correspondre au sharepoint correspondance d’origine”.

Vous pouvez en faire autant que vous voulez, et ce sera un “et”. Exemple:

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

Vous pouvez même append des groupes de capture dans les expressions non consommasortingces si vous avez besoin d’enregistrer certaines données.

Vous devez utiliser lookahead comme l’ont dit certains autres intervenants, mais le lookahead doit prendre en compte d’autres caractères entre son mot cible et la position de correspondance actuelle. Par exemple:

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

Le .* Dans le premier lookhead lui permet de faire correspondre le nombre de caractères requirejs avant qu’il n’atteigne “word1”. Ensuite, la position de correspondance est réinitialisée et la seconde recherche recherche “word2”. Réinitialiser, et la dernière partie correspond à “word3”; comme c’est le dernier mot que vous cherchez, il n’est pas nécessaire que ce soit dans un lookahead, mais ça ne fait pas de mal.

Pour faire correspondre un paragraphe entier, vous devez ancrer le regex aux deux extrémités et append un final .* Pour consumr les caractères restants. En utilisant la notation de style Perl, ce serait:

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

Le modificateur ‘m’ est pour le mode multline; il laisse les correspondances ^ et $ aux limites des paragraphes (“limites de lignes” dans les expressions rationnelles). Dans ce cas, il est essentiel de ne pas utiliser le modificateur ‘s’, qui permet au métacaractère des points de correspondre aux nouvelles lignes ainsi qu’à tous les autres caractères.

Enfin, vous voulez vous assurer que vous associez des mots entiers et pas seulement des fragments de mots plus longs, vous devez donc append des limites de mots:

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

Regardez cet exemple:

Nous avons 2 regexps A et B et nous voulons les faire correspondre, donc en pseudo-code, cela ressemble à ceci:

 pattern = "/A AND B/" 

Il peut être écrit sans utiliser l’opérateur AND comme ceci:

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

dans PCRE:

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

Vous pouvez le faire avec une expression régulière, mais vous en voudrez sûrement. Par exemple, utilisez plusieurs expressions rationnelles et combinez-les dans une clause if.

Vous pouvez énumérer toutes les permutations possibles avec une expression rationnelle standard, comme ceci (correspond à a, b et c dans n’importe quel ordre):

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

Cependant, cela fait une expression rationnelle très longue et probablement inefficace, si vous avez plus que quelques termes.

Si vous utilisez une version regexp étendue, comme celle de Perl ou Java, ils disposent de meilleures méthodes pour y parvenir. D’autres réponses suggèrent d’utiliser l’opération

L’opérateur AND est implicite dans la syntaxe RegExp.
L’opérateur OR doit être spécifié avec un tube.
Le RegExp suivant:

 var re = /ab/; 

signifie la lettre a et la lettre b .
Il fonctionne également avec des groupes:

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

cela signifie le groupe co et le groupe de .
Remplacer le (implicite) ET par un OU nécessiterait les lignes suivantes:

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

Pourquoi ne pas utiliser awk?
avec awk regex AND, OR, c’est tellement simple

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

N’est-il pas possible dans votre cas de faire le AND sur plusieurs résultats correspondants? en pseudocode

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

Si vous utilisez des expressions régulières Perl, vous pouvez utiliser le lookahead positif:

Par exemple

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

serait des nombres supérieurs à 100 et divisibles par 5

Vous pouvez diriger votre sortie vers une autre regex. En utilisant grep, vous pouvez faire ceci:

grep A | grep B

En plus de la réponse acceptée

Je vais vous fournir des exemples pratiques qui clarifieront les choses pour certains d’entre vous. Par exemple, disons que nous avons ces trois lignes de texte:

 [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] 

Voir la démo ici DEMO

Ce que nous voulons faire ici, c’est sélectionner le signe +, mais seulement s’il est après deux nombres avec un espace et s’il est précédé de quatre chiffres. Ce sont les seules contraintes. Nous utiliserions cette expression régulière pour y parvenir:

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

Notez que si vous séparez l'expression, cela vous donnera des résultats différents.

Ou peut-être vous voulez sélectionner du texte entre les balises ... mais pas les balises! Ensuite, vous pouvez utiliser:

 '~(?< =

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

pour ce texte:

 

Hello !

I wont select tags! Only text with in

Voir la démo ici DEMO

Utilisez ET en dehors de l’expression régulière. En PHP, l’opérateur lookahead ne semblait pas fonctionner pour moi, au lieu de cela je l’ai utilisé

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

La regex ci-dessus correspondra si la longueur du mot de passe est de 3 caractères ou plus et qu’il n’y a pas d’espace dans le mot de passe.

L’ordre est toujours impliqué dans la structure de l’expression régulière. Pour accomplir ce que vous voulez, vous devez faire correspondre la chaîne d’entrée plusieurs fois avec différentes expressions.

Ce que vous voulez faire n’est pas possible avec une seule expression rationnelle.