web-dev-qa-db-fra.com

Regex - comment faire correspondre tout sauf un motif particulier

Comment puis-je écrire une regex pour faire correspondre une chaîne qui ne rencontre pas un modèle particulier? Je suis confronté à une situation où je dois faire correspondre un motif (A et ~ B).

165
notnot

Vous pouvez utiliser une affirmation d'anticipation:

(?!999)\d{3}

Cet exemple correspond à trois chiffres autres que 999.


Mais si vous n'avez pas d'implémentation d'expression régulière avec cette fonctionnalité (voir Comparaison des saveurs d'expressions régulières ), vous devez probablement créer une expression régulière avec les fonctionnalités de base par vous-même.

Une expression régulière compatible avec la syntaxe de base uniquement serait:

[0-8]\d\d|\d[0-8]\d|\d\d[0-8]

Cela correspond également à toute séquence de trois chiffres autre que 999.

189
Gumbo

Si vous souhaitez faire correspondre un mot A dans une chaîne et non à un mot B. Par exemple: Si vous avez un texte:

1. I have a two pets - dog and a cat
2. I have a pet - dog

Si vous souhaitez rechercher des lignes de texte qui AVEZ un chien pour un animal domestique et N'AVEZ PAS de chat, vous pouvez utiliser cette expression régulière:

^(?=.*?\bdog\b)((?!cat).)*$

Il ne trouvera que la deuxième ligne:

2. I have a pet - dog
28
Aleks

Faites correspondre le modèle et utilisez le langage hôte pour inverser le résultat booléen de la correspondance. Ce sera beaucoup plus lisible et maintenable.

15
Ben S

non pas, ressusciter cette question ancienne car il avait une solution simple qui n'a pas été mentionnée. (Vous avez trouvé votre question en effectuant des recherches pour une quête de prime regex .)

Je suis confronté à une situation où je dois faire correspondre un motif (A et ~ B).

La regex de base pour cela est extrêmement simple: B|(A)

Vous ignorez simplement les correspondances globales et examinez les captures du groupe 1, qui contiendront A.

Un exemple (avec toutes les clauses de non-responsabilité concernant l'analyse du code HTML dans les expressions rationnelles): A représente les chiffres, B représente les chiffres au sein de <a tag

La regex: <a.*?<\/a>|(\d+)

Démo (regardez le groupe 1 dans le volet inférieur droit)

Référence

Comment faire correspondre un modèle sauf dans les situations s1, s2, s

Comment faire correspondre un modèle sauf si ...

7
zx81

Le complément d'un langage standard est également un langage standard, mais pour le construire, vous devez construire le DFA pour le langage standard et transformer tout changement d'état valide en erreur. Voir this pour un exemple. La page ne dit pas qu'elle convertit /(ac|bd)/ en /(a[^c]?|b[^d]?|[^ab])/. La conversion d'un fichier DFA en une expression régulière n'est pas anodine. Il est plus facile si vous pouvez utiliser l'expression régulière inchangée et modifier la sémantique dans le code, comme suggéré précédemment.

4
Juliano

modèle - re

str.split(/re/g) 

retournera tout sauf le motif.

Test ici

1
unigogo
(B)|(A)

puis utilisez ce que le groupe 2 capture ...

0
DW.

Ma réponse ici pourrait également résoudre votre problème:

https://stackoverflow.com/a/27967674/543814

  • Au lieu de remplacer, vous utiliseriez Match.
  • Au lieu du groupe $1, vous liriez le groupe $2.
  • Le groupe $2 a été créé sans capture, ce que vous éviteriez.

Exemple:

Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");

Le premier groupe de capture spécifie le motif que vous souhaitez éviter. Le dernier groupe de capture capture tout le reste. Lisez simplement ce groupe, $2.

0
Timo