Expression régulière pour une chaîne contenant un mot mais pas un autre

103

Je mets en place des objectifs dans Google Analytics et pourrais utiliser un peu d'aide regex.

Disons que j'ai 4 URL

http://www.anydotcom.com/test/search.cfm?metric=blah&selector=size&value=1
http://www.anydotcom.com/test/search.cfm?metric=blah2&selector=style&value=1
http://www.anydotcom.com/test/search.cfm?metric=blah3&selector=size&value=1
http://www.anydotcom.com/test/details.cfm?metric=blah&selector=size&value=1

Je souhaite créer une expression qui identifiera toute URL qui contient la chaîne selector = size mais ne contient PAS de details.cfm

Je sais que pour trouver une chaîne qui ne contient PAS d'autre chaîne, je peux utiliser cette expression:

(^((?!details.cfm).)*$)

Mais, je ne suis pas sûr de savoir comment ajouter la partie selector = size .

Toute aide serait grandement appréciée!

Chris Stahl
la source

Réponses:

144

Cela devrait le faire:

^(?!.*details\.cfm).*selector=size.*$

^.*selector=size.*$devrait être suffisamment clair. Le premier bit, (?!.*details.cfm)est une anticipation négative: avant de faire correspondre la chaîne, il vérifie que la chaîne ne contient pas "details.cfm" (avec un nombre quelconque de caractères devant lui).

Kobi
la source
8
FYI, consultez regexr.com pour une bonne façon de tester ces expressions.
Joshua Pinter
Oubliez toujours les anticipations négatives et c'est si utile
Alexei Blue
"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0est incorrect. (Notez que la chaîne contient "...selector=sized...".) Aussi, pourquoi .*$à la fin?
Cary Swoveland
4

regex pourrait être (syntaxe perl):

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/`
Djipko
la source
Ceci est une expression régulière corrompue, les crochets transforment toutes les séquences de motifs en combinaison de caractères individuels.
Wiktor Stribiżew
2
^(?=.*selector=size)(?:(?!details\.cfm).)+$

Si votre moteur regex prend en charge les quantificateurs posessifs (bien que je soupçonne que Google Analytics ne le fait pas), je suppose que cela fonctionnera mieux pour les grands ensembles d'entrées:

^[^?]*+(?<!details\.cfm).*?selector=size.*$
Tomalak
la source
Cela suppose que selector=sizec'est toujours avant details.cfm, ce qui n'est pas le cas dans la dernière URL.
Kobi
Juste pour clarifier ça, ce n'était pas moi. Je ne vois pas pourquoi quelqu'un voterait contre deux réponses ici, elles sont toutes les deux correctes.
Kobi
@Kobi: Cela aurait dû être une anticipation, corrigé. Oh et au fait, je ne soupçonnais pas que c'était votre vote négatif.
Tomalak
0

Je cherchais un moyen d'éviter --line-bufferedsur une queue dans une situation similaire car la solution OP et Kobi fonctionne très bien pour moi. Dans mon cas, l'exclusion des lignes avec "bot" ou "spider" tout en incluant ' / '(pour mon document racine).

Ma commande d'origine:

tail -f mylogfile | grep --line-buffered -v 'bot\|spider' | grep ' / '

Devient maintenant (avec le -Pcommutateur perl):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
roon
la source