Évidemment, vous pouvez utiliser le |
(pipe?) Pour représenter OR
, mais existe-t-il un moyen de représenter AND
également?
Plus précisément, je voudrais faire correspondre des paragraphes de texte qui contiennent TOUS une certaine phrase, mais sans ordre particulier.
I'd like to match paragraphs of text
.. 2. Contenant un texte en panne . Le numéro 1 est ouvert à l'interprétation. Le numéro 2 peut être fait de deux manières. Voie 1:,(?:(?:(?(1)(?!))\b(phrase1)\b.*?|(?(2)(?!))\b(phrase2)\b.*?)){2}
Voie 2:(?=.*\bphrase1\b)(?=.*\bphrase2\b)
où dans ce cas, l'appariement du paragraphe dans ce cas n'est pas défini jusqu'à ce que la définition du paragraphe soit formalisée.Réponses:
Utilisez une expression régulière non consommatrice.
La notation typique (c'est-à-dire Perl / Java) est:
(?=
expr)
Cela signifie "match expr mais après cela, continuez de faire correspondre le 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 devez y enregistrer certaines données.
la source
Vous devez utiliser l'anticipation comme l'ont dit certains des autres répondants, mais l'anticipation doit tenir compte des autres caractères entre son mot cible et la position de correspondance actuelle. Par exemple:
Le
.*
premier lookahead lui permet de faire correspondre le nombre de caractères dont il a besoin avant d'arriver à "word1". Ensuite, la position de correspondance est réinitialisée et le deuxième moteur de recherche recherche "word2". Réinitialisez à nouveau et la partie finale correspond à "word3"; puisque c'est le dernier mot que vous recherchez, il n'est pas nécessaire qu'il soit dans une impasse, mais cela ne fait pas de mal.Pour faire correspondre un paragraphe entier, vous devez ancrer l'expression régulière aux deux extrémités et ajouter une finale
.*
pour consommer les caractères restants. En utilisant la notation de style Perl, ce serait:Le modificateur «m» est pour le mode multiligne; il laisse le
^
et$
correspondre aux limites de paragraphe ("limites de ligne" en regex-parler). Dans ce cas, il est essentiel de ne pas utiliser le modificateur «s», qui permet au métacaractère point de correspondre aux nouvelles lignes ainsi qu'à tous les autres caractères.Enfin, vous voulez vous assurer que vous faites correspondre des mots entiers et pas seulement des fragments de mots plus longs, vous devez donc ajouter des limites de mots:
la source
.*
par[\s\S]*
en javascript si vous avez de nouvelles lignes car.
dans le moteur regex de javascript ne correspond pas aux nouvelles lignes et ne peut pas être fait avec des modificateursRegardez cet exemple:
Nous avons 2 regexps A et B et nous voulons faire correspondre les deux, donc en pseudo-code, cela ressemble à ceci:
Il peut être écrit sans utiliser l'opérateur AND comme ceci:
dans PCRE:
la source
(?=expr)
ne fonctionne pas. Cela semble dépendre de la mise en œuvre.^
signifie pas "début de chaîne" dans la syntaxe des expressions rationnelles?^
négation n'est qu'au début d'une classe de caractères. À moins que CMake ne fasse quelque chose de vraiment génial (au point où appeler leur langage de correspondance de motifs "regex" pourrait être considéré comme trompeur ou incorrect), je suppose que le fait que cela a fonctionné pour vous était un accident isolé.Vous pouvez le faire avec une expression régulière, mais vous voudrez probablement en avoir d'autres. 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):
Cependant, cela fait une expression rationnelle très longue et probablement inefficace, si vous avez plus de deux termes.
Si vous utilisez une version regexp étendue, comme Perl ou Java, ils ont de meilleures façons de le faire. D'autres réponses ont suggéré d'utiliser une opération d'anticipation positive.
la source
a(bc|cb)|b(ac|ca)|c(ab|ba)
. Et le plus important, vous pouvez l'utiliser avec toutes les saveurs regex.L'opérateur AND est implicite dans la syntaxe RegExp.
L'opérateur OR doit plutôt être spécifié avec un tuyau.
Le RegExp suivant:
signifie la lettre
a
ET la lettreb
.Il fonctionne également avec des groupes:
cela signifie le groupe
co
ET le groupede
.Remplacer le (implicite) ET par un OU nécessiterait les lignes suivantes:
la source
N'est-il pas possible dans votre cas de faire l'AND sur plusieurs résultats correspondants? en pseudocode
la source
Pourquoi ne pas utiliser awk?
avec awk regex ET, OU les choses sont si simples
la source
Si vous utilisez des expressions régulières Perl, vous pouvez utiliser l'anticipation positive:
Par exemple
serait un nombre supérieur à 100 et divisible par 5
la source
Vous pouvez diriger votre sortie vers une autre expression régulière. En utilisant grep, vous pouvez faire ceci:
grep A | grep B
la source
En plus de la réponse acceptée
Je vais vous fournir quelques exemples pratiques qui clarifieront les choses pour certains d'entre vous. Par exemple, disons que nous avons ces trois lignes de texte:
Voir la démo ici DEMO
Ce que nous voulons faire ici, c'est sélectionner le signe + mais seulement si c'est après deux nombres avec un espace et si c'est avant quatre nombres. Ce sont les seules contraintes. Nous utiliserions cette expression régulière pour y parvenir:
Notez que si vous séparez l'expression, cela vous donnera des résultats différents.
Ou peut-être voulez-vous sélectionner du texte entre les balises ... mais pas les balises! Ensuite, vous pouvez utiliser:
pour ce texte:
Voir la démo ici DEMO
la source
L'ordre est toujours impliqué dans la structure de l'expression régulière. Pour accomplir ce que vous voulez, vous devrez 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.
la source
Utilisez AND en dehors de l'expression régulière. En PHP lookahead, l'opérateur ne semblait pas fonctionner pour moi, mais j'ai utilisé
Le 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'espaces dans le mot de passe.
la source