901 votes

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

De toute évidence, vous pouvez utiliser |(pipe?) pour représenter OR, mais pouvez-vous également faire correspondre and ?

Plus précisément, je veux faire correspondre des paragraphes de texte qui contiennent TOUTES une certaine expression, mais sans ordre particulier.

464voto

Jason Cohen Points 36475

Utilisez une expression régulière non consommatrice.

La notation typique (ie Perl / Java) est:

(?= expr )

Cela signifie "match expr mais après cela continuer à correspondre au point de correspondance d'origine."

Vous pouvez en faire autant que vous le souhaitez, et ce sera un "et". Exemple:

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

Vous pouvez même ajouter des groupes de capture à l'intérieur des expressions non consommatrices si vous avez besoin d'en sauvegarder certaines données.

432voto

Alan Moore Points 39365

Vous avez besoin d'utiliser d'anticipation que d'autres intervenants l'ont dit, mais l'anticipation a de compte pour les autres caractères entre son mot cible et le match en cours position. Par exemple:

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

L' .* dans la première anticipation permet de match toutefois le nombre de caractères, il doit avant qu'il arrive à "mot1". Puis le match position est remise à zéro et la seconde d'anticipation à la recherche de "mot2". Reset encore une fois, et la dernière partie correspond à "terme3"; parce qu'il est le dernier mot que vous êtes en vérifiant, il n'est pas nécessaire qu'il soit dans une anticipation, mais il ne fait pas de mal.

Afin de faire correspondre un paragraphe entier, vous avez besoin pour ancrer la regex aux deux extrémités et ajouter une dernière .* à consommer les caractères restants. À l'aide de Perl-style de notation, ce serait:

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

Le 'm' de modificateur pour multline mode; il permet à l' ^ et $ match au paragraphe limites ("ligne de limites" dans la regex parler). Il est essentiel, dans ce cas, vous ne pas utiliser le " s " modificateur, ce qui permet à la dot métacaractère match des retours à la ligne ainsi que tous les autres personnages.

Enfin, vous voulez vous assurer que vous êtes correspondant à des mots entiers et pas seulement des fragments de mots plus longs, vous devez ajouter des limites de mots:

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

54voto

fanjabi Points 452

Regardez cet exemple:

Nous avons 2 regexps A et B et nous voulons faire correspondre les deux, donc dans le pseudo-code il 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)
 

30voto

Juha Syrjälä Points 11475

Vous pouvez le faire avec une expression régulière, mais probablement vous aurez envie de quelque chose. Pour reprendre l'exemple de plusieurs regexp et de les combiner dans une si la clause.

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

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

Cependant, cela fait un très long et probablement inefficace regexp, si vous avez plus de quelques termes.

Si vous utilisez certains prolongée regexp version, comme Perl ou Java, ils ont de meilleures façons de le faire. D'autres réponses ont suggéré l'utilisation d'anticipation positif de l'opération.

15voto

user54579 Points 1404

N'est-il pas possible dans votre cas de faire l'ET sur plusieurs résultats correspondants? en pseudocode

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X