Comment dois-je écrire une expression régulière pour correspondre à un mot spécifique?

21

J'ai essayé de faire fonctionner une expression rationnelle spécifique mais je n'arrive pas à faire ce dont j'ai besoin.

Fondamentalement, je veux qu'il cherche ROCKET. L'expression régulière doit correspondre à ROCKET en majuscules ou en minuscules, avec ou sans ponctuation, mais pas lorsqu'elle fait partie d'un autre mot. Ainsi, l'expression régulière se déclencherait sur l'un de ces éléments:

rocket
RoCKEt
hi Rocket
This is a rocket.
ROCKET's engine

mais PAS déclencher sur ROCKET quand il se trouve dans quelque chose comme

Rocketeer
Sprocket

J'ai essayé de faire les choses correctement en utilisant un générateur de regex en ligne, mais je ne peux pas le faire correspondre exactement.

Kefka
la source
1
Il s'agit de l'une de ces situations [peu fréquentes] où la question pourrait être mieux adaptée au débordement de pile. Assurez-vous de fournir une langue et / ou une plate-forme car chaque langue a ses propres particularités. Par exemple, Windows. .Net et la classe Regex . (Habituellement, c'est l'inverse. Stack Overflow reçoit des centaines de questions hors sujet de développeurs qui conviennent mieux à Super User).
2015 à 22h14

Réponses:

14

Je suggère de mettre en signet le MSDN Regular Expression Quick Reference

vous souhaitez obtenir une correspondance insensible à la casse pour le mot "fusée" entouré de caractères non alphanumériques. Une expression rationnelle qui fonctionnerait serait:

\W*((?i)rocket(?-i))\W*

Ce qu'il fera, c'est rechercher zéro ou plusieurs (*) caractères non alphanumériques (\ W), suivis d'une version non sensible à la casse de la fusée ((? I) fusée (? - i)), suivie à nouveau par zéro ou plus ( *) caractères non alphanumériques (\ W). Les parenthèses supplémentaires autour du terme de correspondance de fusée attribuent la correspondance à un groupe distinct. Le mot fusée sera donc dans le groupe de matches 1.

MISE À JOUR 1: Matt a déclaré dans le commentaire que cette expression régulière devait être utilisée en python. Python a une syntaxe légèrement différente. Pour obtenir le même résultat en python, utilisez cette expression régulière et passez l' re.IGNORECASEoption à la fonction compileor match.

\W*(rocket)\W*

Sur Regex101, cela peut être simulé en entrant "i" dans la zone de texte à côté de l'entrée regex.

MISE À JOUR 2 Ismael a mentionné que l'expression régulière n'est pas tout à fait correcte, car elle pourrait correspondre à "1rocket1". Il a affiché une bien meilleure solution, à savoir

(?:^|\W)rocket(?:$|\W)

Xaser
la source
1
Le tester en ligne avec des testeurs regex en ligne ( regex101.com par exemple) le montre comme des chaînes d'exemple non valides et ne correspondant pas que j'entre. Il est destiné à être utilisé dans le cadre d'un script python. Cela fait-il une différence dans la façon dont il devrait être écrit?
Kefka
1
Oui. vous pouvez voir sur regex101.com que vous pouvez choisir une "saveur" regex en haut à gauche, le python est légèrement différent. Je mettrai à jour ma réponse avec l'équivalent python.
Xaser
1
Merci. Je pensais que les expressions rationnelles étaient fondamentalement indépendantes de la langue.
Kefka
1
Ils devraient l'être, mais des différences mineures de mise en œuvre existent.
Xaser
2
Et des \W*(rocket)\W*allumettes lrocketl. Il devrait l'être (?:^|\W)(rocket)(?:$|\W)(sans le *et vous devez vérifier s'il correspond au début et / ou à la fin de la chaîne).
Ismael Miguel
10

Je pense que les perspectives sont exagérées dans ce cas, et vous feriez mieux d'utiliser les limites de mots avec l' ignorecaseoption,

\brocket\b

En d'autres termes, en python:

>>> x="rocket's"
>>> y="rocket1."
>>> c=re.compile(r"\brocket\b",re.I)  # with the ignorecase option
>>> c.findall(y)
[]
>>> c.findall(x)
['rocket']
Beroe
la source
techniquement, les groupes non capturants ne sont pas des solutions de contournement, mais l'option / b donne exactement le même résultat que la solution d'Ismael, mais peut être un peu plus élégante.
Xaser
1

Avec grepet sed, vous pouvez utiliser \<rocket\>. Avec grep, l' -ioption la rendra insensible à la casse ( je ne sais pas la casse):

grep -i '\<rocket\>'

Je ne connais aucun moyen de rendre tous les sedregex insensibles à la casse, mais il y a toujours la façon de l'homme des cavernes:

sed -n '/\<[Rr][Oo][Cc][Kk][Ee][Tt]\>/p'
Scott
la source
0

Utilisez l'option Rechercher uniquement les mots entiers.

En ce qui concerne les ponctuations, vous ne pouvez pas y répondre avant de connaître la saveur / la saveur.

C'est un fil très ancien, donc publié pour quelqu'un qui pourrait visiter avec un besoin plus tard. Ceux qui sont à l'origine du fil peuvent être passés à autre chose ... Non?

Rex Schweiss
la source
Qu'est-ce qui whole words only optionutilise grepou php? Désolé, mais votre réponse ne donne aucune valeur ajoutée par rapport aux autres réponses.
Toto