Regex: correspond à tout sauf à un motif spécifique
310
J'ai besoin d'une expression régulière capable de tout faire correspondre, sauf une chaîne commençant par un modèle spécifique (spécifiquement index.phpet ce qui suit, comme index.php?id=2342343)
Et quel modèle spécifique voulez-vous ne pas faire correspondre?
Dominic Rodger
2
Y a-t-il une raison pour laquelle vous ne pouvez pas faire de correspondance avec votre modèle et ne pas faire quelque chose si la chaîne correspond à cela?
@ThomasOwens: Cela dépend. Cela dépend de quelle partie de l'expression doit être annulée. Si l'expression entière doit être niée, alors vous avez un point. Par exemple, si vous voulez coder "si la chaîne ne contient pas 'Bruce' comme sous-chaîne, alors faites quelque chose", vous utiliserez simplement / Bruce /, et placerez la négation dans l'instruction if, en dehors de l'expression régulière . Mais il se pourrait que vous souhaitiez annuler une sous-expression. Dites, vous recherchez quelque chose comme prénom nom de famille, où le prénom est Bruce, et le nom de famille est tout sauf XYZ, où XYZ est le nom de famille d'une célébrité appelée Bruce.
mathheadinclouds
Réponses:
250
Pas un expert en regexp, mais je pense que vous pouvez utiliser un lookahead négatif dès le début, par exemple ^(?!foo).*$ne devrait pas correspondre à quoi que ce soit commençant par foo.
Autres moteurs permettant des contournements: (cat)|[^c]*(?:c(?!at)[^c]*)*(ou (?s)(cat)|(?:(?!cat).)*, ou (cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*) et ensuite vérifier avec la langue signifie: si le groupe 1 correspond, ce n'est pas ce dont nous avons besoin, sinon, saisissez la valeur de correspondance sinon vide
un certain caractère unique ou un ensemble de caractères :
Remarque sur la démo : la nouvelle ligne \nest utilisée à l'intérieur des classes de caractères annulées dans les démos pour éviter un débordement de correspondance avec la ou les lignes voisines. Ils ne sont pas nécessaires lors du test de chaînes individuelles.
Note d'ancrage : dans de nombreuses langues, utilisez \Apour définir le début de la chaîne sans ambiguïté et \z(en Python, c'est \Z, en JavaScript, $c'est OK) pour définir la fin de la chaîne.
Remarque : dans de nombreuses versions (mais pas POSIX, TRE, TCL), .correspond à n'importe quel caractère, à l'exception d' un caractère de nouvelle ligne . Assurez-vous d'utiliser un modificateur DOTALL correspondant ( /sdans PCRE / Boost / .NET / Python / Java et /mdans Ruby) pour .correspondre à n'importe quel caractère, y compris une nouvelle ligne.
Remarque\n sur les barres obliques inverses : dans les langues où vous devez déclarer des modèles avec des chaînes C permettant des séquences d'échappement (comme pour une nouvelle ligne), vous devez doubler les barres obliques inverses qui échappent aux caractères spéciaux afin que le moteur puisse les traiter comme des caractères littéraux (par exemple en Java, world\.sera déclaré en tant que "world\\.", ou utilisez une classe de caractères:) "world[.]". Utilisez des littéraux de chaîne bruts (Python r'\bworld\b'), des littéraux de chaîne verbatim C # @"world\."ou des notations littérales de chaînes slashy / regex comme /world\./.
Grande écriture! Dans le cas d'une "chaîne (non) égale à une chaîne", avec l'exemple de ^(?!foo$), pourquoi le signe dollar doit-il être entre parenthèses pour que l'expression fonctionne? Je m'attendais ^(?!foo)$à donner les mêmes résultats, mais ce n'est pas le cas.
Grant Humphries du
3
@GrantHumphries: lorsque l' $ancre est à l'intérieur de l'antichambre, elle fait partie de la condition, de cette assertion de largeur nulle . S'il était à l'extérieur, comme dans ^(?!foo)$, il fera partie du modèle de consommation nécessitant la fin de la chaîne juste après le début de la chaîne, ce qui rendrait l'anticipation négative non pertinente car elle retournerait toujours vrai (il ne peut y avoir de texte après la fin de la chaîne , encore moins foo). Ainsi, ^(?!foo$)correspond au début d'une chaîne qui n'est pas suivie par foocelle qui est suivie par la fin de la chaîne. ^(?!foo)$correspond à une chaîne vide.
Wiktor Stribiżew
@ robots.txt Veuillez supprimer ces commentaires. Vous posez une question XY. Les classes de caractères sont censées correspondre à des caractères uniques, il n'y a aucun moyen de définir une séquence de caractères avec eux. Vous devriez probablement trouver la sous-chaîne entre le début d'une chaîne et la première occurrence de cotor lan, et supprimer la correspondance, comme regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Par exemple, votre réponse liée échoue dans cet exemple "ing packages <! - et la page Web <! - asdasasdas -> les éditeurs utilisent maintenant -> Lorem Ipsum"
MonsterMMORPG
259
Vous pouvez mettre un ^au début d'un jeu de caractères pour correspondre à tout sauf à ces caractères.
C'est vrai, mais il ne traite qu'un caractère à la fois. Si vous souhaitez exclure une séquence de deux ou plusieurs caractères, vous devez utiliser l'anticipation négative comme l'ont dit les autres répondants.
Alan Moore
solution parfaite pour supprimer tous les caractères indésirables, sauf ceux du motif. merci
Sirmyself
@Alan, "... vous devez utiliser une anticipation négative ..." est incorrect, mais nous ne devrions pas être trop durs avec vous parce que Wiktor n'a pas posté sa réponse - ce qui montre pourquoi - jusqu'en 2016.
Cary Swoveland
6
Faites simplement correspondre /^index\.php/puis rejetez ce qui correspond.
Je besoin d' un regex capable de correspondre à tout , mais excepter une chaîne commençant parindex.php un motif spécifique ( en particulier index.php et ce qui suit, comme index.php? Id = 2342343)
L'OP a spécifiquement demandé une expression régulière ... Je ne suis pas sûr que cela aide! (Il peut utiliser grepsur la ligne de commande, par exemple, ou Perl / Python / tout autre langage, ou une commande "Exécuter cette expression régulière pour chaque ligne" dans un éditeur de texte, etc ...)
Réponses:
Pas un expert en regexp, mais je pense que vous pouvez utiliser un lookahead négatif dès le début, par exemple
^(?!foo).*$
ne devrait pas correspondre à quoi que ce soit commençant parfoo
.la source
^((?!foo).)*$
( stackoverflow.com/a/406408/3964381 )Regex: correspond à tout, mais :
foo
):^(?!foo).*$
^(?!foo)
^(([^f].{2}|.[^o].|.{2}[^o]).*|.{0,2})$
^([^f].{2}|.[^o].|.{2}[^o])|^.{0,2}$
world.
à la fin):(?<!world\.)$
^.*(?<!world\.)$
^(.*([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.])|.{0,5})$
([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.]$|^.{0,5})$
foo
) (pas de patern conforme POSIX, désolé):^(?!.*foo)
^(?!.*foo).*$
|
symbole):^[^|]*$
foo
):^(?!foo$)
^(?!foo$).*$
^(.{0,2}|.{4,}|[^f]..|.[^o].|..[^o])$
cat
):/cat(*SKIP)(*FAIL)|[^c]*(?:c(?!at)[^c]*)*/i
ou/cat(*SKIP)(*FAIL)|(?:(?!cat).)+/is
(cat)|[^c]*(?:c(?!at)[^c]*)*
(ou(?s)(cat)|(?:(?!cat).)*
, ou(cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*
) et ensuite vérifier avec la langue signifie: si le groupe 1 correspond, ce n'est pas ce dont nous avons besoin, sinon, saisissez la valeur de correspondance sinon vide[^a-z]+
(tout caractère autre qu'une lettre ASCII minuscule)|
:[^|]+
Remarque sur la démo : la nouvelle ligne
\n
est utilisée à l'intérieur des classes de caractères annulées dans les démos pour éviter un débordement de correspondance avec la ou les lignes voisines. Ils ne sont pas nécessaires lors du test de chaînes individuelles.Note d'ancrage : dans de nombreuses langues, utilisez
\A
pour définir le début de la chaîne sans ambiguïté et\z
(en Python, c'est\Z
, en JavaScript,$
c'est OK) pour définir la fin de la chaîne.Remarque : dans de nombreuses versions (mais pas POSIX, TRE, TCL),
.
correspond à n'importe quel caractère, à l'exception d' un caractère de nouvelle ligne . Assurez-vous d'utiliser un modificateur DOTALL correspondant (/s
dans PCRE / Boost / .NET / Python / Java et/m
dans Ruby) pour.
correspondre à n'importe quel caractère, y compris une nouvelle ligne.Remarque
\n
sur les barres obliques inverses : dans les langues où vous devez déclarer des modèles avec des chaînes C permettant des séquences d'échappement (comme pour une nouvelle ligne), vous devez doubler les barres obliques inverses qui échappent aux caractères spéciaux afin que le moteur puisse les traiter comme des caractères littéraux (par exemple en Java,world\.
sera déclaré en tant que"world\\."
, ou utilisez une classe de caractères:)"world[.]"
. Utilisez des littéraux de chaîne bruts (Pythonr'\bworld\b'
), des littéraux de chaîne verbatim C #@"world\."
ou des notations littérales de chaînes slashy / regex comme/world\./
.la source
^(?!foo$)
, pourquoi le signe dollar doit-il être entre parenthèses pour que l'expression fonctionne? Je m'attendais^(?!foo)$
à donner les mêmes résultats, mais ce n'est pas le cas.$
ancre est à l'intérieur de l'antichambre, elle fait partie de la condition, de cette assertion de largeur nulle . S'il était à l'extérieur, comme dans^(?!foo)$
, il fera partie du modèle de consommation nécessitant la fin de la chaîne juste après le début de la chaîne, ce qui rendrait l'anticipation négative non pertinente car elle retournerait toujours vrai (il ne peut y avoir de texte après la fin de la chaîne , encore moinsfoo
). Ainsi,^(?!foo$)
correspond au début d'une chaîne qui n'est pas suivie parfoo
celle qui est suivie par la fin de la chaîne.^(?!foo)$
correspond à une chaîne vide.cot
orlan
, et supprimer la correspondance, commeregex.replace(myString, "^.*?(?:cot|lan)\s*", "")
.Vous pouvez mettre un
^
au début d'un jeu de caractères pour correspondre à tout sauf à ces caractères.correspondra à tout, mais
=
la source
Faites simplement correspondre
/^index\.php/
puis rejetez ce qui correspond.la source
str !~ /\Aindex\.php/
.En python:
la source
Utiliser la méthode Exec
OU AUTRE MATCH
la source
Que diriez-vous de ne pas utiliser regex:
la source
grep
sur la ligne de commande, par exemple, ou Perl / Python / tout autre langage, ou une commande "Exécuter cette expression régulière pour chaque ligne" dans un éditeur de texte, etc ...)