2010-06-01 14 views
62

Je définis des objectifs dans Google Analytics et j'aurais besoin d'un peu d'aide sur la regex.Expression régulière pour une chaîne contenant un mot mais pas un autre

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 veux créer une expression qui permettra d'identifier toute URL contenant la chaîne sélecteur = taille mais ne contient pas details.cfm

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

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

Mais, je ne sais pas comment ajouter dans la partie selector = taille.

Toute aide serait grandement appréciée!

Répondre

86

Cela devrait le faire:

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

^.*selector=size.*$ doit être suffisamment clair. Le premier bit, (?!.*details.cfm) est un look-ahead négatif: 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 avant).

+2

Pour votre information, consultez http://www.regexr.com/ pour une belle manière de tester ces expressions. –

+0

Brillant, cela a aidé. Bonne explication – user219628

+0

Toujours oublier le lookahead négatif et c'est tellement utile –

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

Si votre moteur de regex supporté posessive quantificateurs (bien que je soupçonne que Google Analytics ne fonctionne pas), alors je suppose que cela fonctionnera mieux pour les grandes entrée fixe:

^[^?]*+(?<!details\.cfm).*?selector=size.*$ 
+0

Cela suppose que 'selector = size' est toujours devant' details.cfm', ce qui n'est pas le cas dans la dernière URL. – Kobi

+0

Juste pour éclaircir ça, ce n'était pas moi. Je ne vois pas pourquoi quelqu'un voterait deux réponses ici, ils ont tous les deux raison. – Kobi

+0

@Kobi: Cela aurait dû être un aperçu, corrigé. Oh, et en passant, je ne pensais pas que c'était votre vote négatif. – Tomalak

5

regex pourrait être (syntaxe perl) :

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/` 
-4

Une façon simple de le faire est de spécifier 0 instances de la chaîne en procédant comme suit

(string_to_exclude){0} 
+2

Cela ne fonctionne pas. –

+0

cela évalue simplement à la chaîne vide; il ne garantit pas que la sous-chaîne ne se produit pas, mais que la chaîne vide se produit, ce qu'elle fait toujours –

0

Je cherchais un moyen d'éviter - ligne-tamponnée sur une queue dans une situation similaire que la solution OP et Kobi fonctionne très bien pour moi. Dans mon cas, excluant les lignes avec "bot" ou "spider" en incluant '/' (pour mon document racine).

Ma commande originale:

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

devient maintenant (avec "-P" commutateur perl):

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