Comment nier l'ensemble de l'expression régulière?

95

J'ai une regex, par exemple (ma|(t){1}). Cela correspond maet tet ne correspond pas bla.

Je veux nier le regex, donc il doit correspondre blaet non maet t, en ajoutant quelque chose à ce regex . Je sais que je peux écrire bla, la regex réelle est cependant plus complexe.

IAdapter
la source
5
En passant, {1}c'est complètement inutile. (Si vous pensez que cela apporte une certaine valeur, pourquoi n'écrivez-vous pas ((m{1}a{1}){1}|(t){1}){1}?)
tripleee

Réponses:

100

Utilisez une recherche négative: (?!pattern)

Des recherches positives peuvent être utilisées pour affirmer qu'un modèle correspond. Les vérifications négatives sont le contraire: elles sont utilisées pour affirmer qu'un modèle NE correspond PAS. Certaines saveurs soutiennent les assertions; certains mettent des limites à regarder en arrière, etc.

Liens vers regular-expressions.info

Voir également

Plus d'exemples

Ce sont des tentatives pour trouver des solutions regex aux problèmes de jouets sous forme d'exercices; ils devraient être éducatifs si vous essayez d'apprendre les différentes façons dont vous pouvez utiliser les lookarounds (les imbriquer, les utiliser pour capturer, etc.):

lubrifiants polygènes
la source
2
regular-expressions.info est une sacrée bonne ressource pour tout ce qui concerne les regex.
Freiheit le
Qu'est-ce que tous ont un support lookaround ? Ne fonctionne pas avec grep.
Lazer
Pattern.compile("(?!(a.*b))").matcher("xab").matches()devrait être true, non?
Karl Richter
4
Il me semble que ce n'est pas correct, voir stackoverflow.com/questions/8610743/… pour une alternative correcte.
Karl Richter
56

En supposant que vous ne vouliez interdire que les chaînes qui correspondent complètement à l'expression régulière (c'est-à-dire que mmblac'est correct, mais mmpas), voici ce que vous voulez:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)est une anticipation négative ; il dit "à partir de la position actuelle, les quelques caractères suivants ne sont pasmm ou t, suivis de la fin de la chaîne." L'ancre de début ( ^) au début garantit que l'anticipation est appliquée au début de la chaîne. Si cela réussit, le.* continue et consomme la chaîne.

Pour info, si vous utilisez la matches()méthode Java , vous n'avez pas vraiment besoin du the ^et du final $, mais ils ne font aucun mal. L' $intérieur de l'anticipation est cependant nécessaire.

Alan Moore
la source
2
La partie la plus utile de cette réponse est que vous devez ajouter .*à la fin de votre regex, sinon elle rejettera chaque chaîne.
Rav
2
L' $ intérieur de l'anticipation négative ET celui .*à la fin sont tous deux des bits critiques. Comme toujours avec les ER, un ensemble solide de tests unitaires est absolument essentiel pour bien faire les choses. Cette réponse est correcte à 100%.
Tom Dibble
1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

c'est pour la regex donnée.
le \ b est de trouver la limite du mot.
le regard positif vers l'avant (? = \ w) est ici pour éviter les espaces.
le regard négatif sur le regex original est d'empêcher les correspondances.
et enfin le (\ w *) est d'attraper tous les mots qui restent.
le groupe qui contiendra les mots est le groupe 3.
le simple (?! motif) ne fonctionnera pas car toute sous-chaîne correspondra
au simple ^ (?! (?: m {2} | t) $). * $ sera ne fonctionne pas car sa granularité est pleine de lignes

Ofer Skulsky
la source
0

Appliquez ceci si vous utilisez laravel.

Laravel a un not_regex où le champ en cours de validation ne doit pas correspondre à l'expression régulière donnée; utilise la preg_matchfonction PHP en interne.

'email' => 'not_regex:/^.+$/i'
DAVID AJAYI
la source