Question Comment annuler un mot spécifique dans regex?


Je sais que je peux nier le groupe de caractères comme dans [^bar] mais j'ai besoin d'une expression régulière où la négation s'applique au mot spécifique - donc dans mon exemple comment nier un réel "bar" et pas "any chars in bar"?


468
2017-08-06 17:20


origine


Réponses:


Une excellente façon de faire est d'utiliser lookahead négatif:

^(?!.*bar).*$

518
2017-08-06 17:38



À moins que la performance ne vous inquiète, il est souvent plus facile d'exécuter vos résultats au cours d'un second passage, en ignorant ceux qui correspondent aux mots que vous voulez annuler.

Les expressions régulières signifient généralement que vous faites des scripts ou une sorte de tâche à faible performance de toute façon, alors trouvez une solution facile à lire, facile à comprendre et à maintenir.


59
2017-08-06 17:33



La regex suivante fera ce que vous voulez (tant que les lookbehinds négatifs et les lookaheads sont supportés), en faisant correspondre les choses correctement; le seul problème est qu'il correspond à des caractères individuels (c'est-à-dire que chaque correspondance est un caractère unique plutôt que tous les caractères entre deux "barres" consécutives), ce qui peut entraîner un surcoût important si vous travaillez avec des chaînes très longues.

b(?!ar)|(?<!b)a|a(?!r)|(?<!ba)r|[^bar]

40
2017-08-06 17:24



Vous pouvez soit utiliser un look-ahead négatif ou look-behind:

^(?!.*?bar).*
^(.(?<!bar))*?$

Ou utilisez simplement les bases:

^(?:[^b]+|b(?:$|[^a]|a(?:$|[^r])))*$

Celles-ci correspondent à tout ce qui ne contient pas bar.


33
2017-09-10 20:44



Je suis tombé sur ce fil de discussion en essayant d'identifier une regex pour l'instruction anglaise suivante:

Étant donné une chaîne d'entrée, correspondez tout  sauf si cette chaîne d'entrée est exactement 'bar'; Par exemple, je veux faire correspondre «barrière» et «disbar» ainsi que «foo».

Voici l'expression rationnelle que je suis venu avec

^(bar.+|(?!bar).*)$

Ma traduction anglaise de la regex est "correspondre à la chaîne si elle commence par" barre "et qu'elle a au moins un autre caractère, ou si la chaîne ne commence pas par" barre ".


23
2017-09-13 16:08



Solution:

^(?!.*STRING1|.*STRING2|.*STRING3).*$

xxxxxx D'accord

xxxSTRING1xxx KO (est-ce que c'est désiré)

xxxSTRING2xxx KO (est-ce que c'est désiré)

xxxSTRING3xxx KO (est-ce que c'est désiré)


20
2018-01-04 00:04



La réponse acceptée est belle mais est vraiment une solution de rechange pour l'absence d'un simple opérateur de négation de sous-expression dans les expressions rationnelles. C'est pourquoi grep --invert-match sorties. Donc, dans * nixes, vous pouvez obtenir le résultat souhaité en utilisant des tuyaux et une seconde regex.

grep 'something I want' | grep --invert-match 'but not these ones'

Encore une solution de contournement, mais peut-être plus facile à retenir.


5
2017-12-06 06:32