Une expression régulière pour exclure un mot / une chaîne

299

J'ai une expression régulière comme suit:

^/[a-z0-9]+$

Cela correspond à des chaînes telles que /helloou /hello123.

Cependant, j'aimerais qu'il exclue quelques valeurs de chaîne telles que /ignoremeet /ignoreme2.

J'ai essayé quelques variantes mais je n'arrive pas à en faire fonctionner!

Ma dernière tentative faible a été

^/(((?!ignoreme)|(?!ignoreme2))[a-z0-9])+$

Toute aide serait grandement appréciée :-)

romiem
la source
1
Copie possible: stackoverflow.com/questions/1395177/…
Anderson Green

Réponses:

376

Voici encore une autre façon (en utilisant une perspective négative ):

^/(?!ignoreme|ignoreme2|ignoremeN)([a-z0-9]+)$ 

Note: Il n'y a qu'une seule expression de capture: ([a-z0-9]+).

Seth
la source
1
Brillant, cela semble avoir fait l'affaire. J'ai en fait besoin de cette règle pour la réécriture d'URL et je voulais ignorer les dossiers "images", "css" et "js". Donc ma règle est la suivante: ^ / (?! Css | js | images) ([az] +) /? (\? (. +))? $ Et il réécrit dans /Profile.aspx?id=$1&$3 Cette règle fonctionnera-t-elle correctement et propagera-t-elle également la chaîne de requête? Donc, si quelqu'un visite mydomain.com/hello?abc=123, je voudrais qu'il réécris dans mydomain.com/Profile.aspx?id=hello&abc=123 Je suis également un peu incertain des performances de (. +) Sur la fin pour capturer la chaîne de requête dans la demande d'origine.
romiem
Cela ressemble à une autre question. L'expression régulière que vous avez ressemble à elle va capturer la chaîne de requête - testez et voyez si votre chaîne de requête arrive. Aussi - (\?(.+))?$devrait être rapide. Je ne m'inquiéterais pas trop de la vitesse.
Seth
1
Cela n'a pas fonctionné pour moi, alors que la solution d'Alix Axel a fonctionné. J'utilise la java.util.regex.Patternclasse de Java .
Mark Jeronimus
1
Je confirme le Mark de Mark;) - par exemple, Pycharm est basé sur Java, n'est-ce pas? Donc, compte tenu des regex dans la recherche Pycharm, la solution d'Alix fonctionne, l'autre non.
fanny
43

Cela devrait le faire:

^/\b([a-z0-9]+)\b(?<!ignoreme|ignoreme2|ignoreme3)

Vous pouvez ajouter autant de mots ignorés que vous le souhaitez, voici une implémentation PHP simple:

$ignoredWords = array('ignoreme', 'ignoreme2', 'ignoreme...');

preg_match('~^/\b([a-z0-9]+)\b(?<!' . implode('|', array_map('preg_quote', $ignoredWords)) . ')~i', $string);
Alix Axel
la source
je pensais que regarder derrière nécessite un motif à largeur fixe?
simon
2
@AlixAxel Oui, mais des librairies regex plus intelligentes permettront une alternance avec des longueurs variables pour les alternatives (et utiliseront la plus longue), tant que chaque alternative est de longueur fixe.
ChrisF
c'est intelligent, mais échoue pour moi si le mot ignoré se trouve à la fin de tout autre mot. c'est-à-dire si vous ajoutez «a» comme un des mots ignorés, alors tout mot qui se termine par un est ignoré
singmotor
21

Comme vous voulez exclure les deux mots, vous avez besoin d'une conjonction:

^/(?!ignoreme$)(?!ignoreme2$)[a-z0-9]+$

Maintenant, les deux conditions doivent être remplies (ni ignoreme ni ignoreme2 ne sont autorisés) pour avoir une correspondance.

Gombo
la source
1
Cela équivaut à celui le plus court ci-dessus qui est une anticipation négative d'un ensemble d'alternatives.
ChrisF
4
@ChrisF Non, pas vraiment. La solution de Seth ne correspondrait pas à quelque chose comme /ignoremenotce qui /est suivi par ignoreme.
Gumbo