2010-06-01 4 views
62

Ich richte einige Ziele in Google Analytics ein und könnte eine kleine Regex-Hilfe verwenden.Regulärer Ausdruck für eine Zeichenfolge, die ein Wort enthält, aber kein anderes

Lets sagen, ich habe 4 URLs

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 

Ich möchte einen Ausdruck erstellen, die eine beliebige URL identifizieren, die die Zeichenfolge Selektor = Größe enthält aber enthält nicht details.cfm

Ich weiß, dass, um einen String zu finden, der KEINEN anderen String enthält, ich diesen Ausdruck verwenden kann:

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

Aber ich bin mir nicht sicher, wie Sie in den selector = Größe Teil hinzufügen.

Jede Hilfe würde sehr geschätzt werden!

Antwort

86

Dies sollte es tun:

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

^.*selector=size.*$ sollte klar genug sein. Das erste Bit, (?!.*details.cfm), ist ein negatives Vorausschau-Argument: vor dem Vergleich mit dem String prüft es, dass der String "details.cfm" nicht enthält (mit einer beliebigen Anzahl von Zeichen davor).

+2

FYI Besuche http://www.regexr.com/ für einen schönen Möglichkeit, diese Ausdrücke zu testen. –

+0

Brilliant, das hat geholfen. Gute Erklärung – user219628

+0

Vergiss immer negatives Lookahead und es ist so nützlich –

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

Wenn Ihre Regex-Engine unterstützt possessiv quantifiers (obwohl ich vermute, Google Analytics nicht), dann denke ich dies für großen Eingang besser abschneiden wird Sätze:

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

Dies setzt voraus, dass 'selector = size' immer vor' details.cfm' steht, was in der letzten URL nicht der Fall ist. – Kobi

+0

Um das zu klären, war ich es nicht. Ich kann nicht verstehen, warum jemand hier zwei Antworten wählt, beide sind richtig. – Kobi

+0

@Kobi: Dies sollte eine Vorausschau sein, korrigiert. Oh, und übrigens, ich habe nicht vermutet, dass es dein Down-Vote war. – Tomalak

5

regex könnte (Perl-Syntax) :

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

einfache Möglichkeit, dies zu tun ist, 0 Instanzen der Zeichenfolge angeben, indem Sie die

folgendermaßen vorgehen
+2

Dies funktioniert nicht. –

+0

dies ergibt einfach den leeren String; es stellt nicht sicher, dass der Teilstring nicht auftritt, sondern dass der leere String auftritt, was er immer tut –

0

Ich suchte nach einem Weg zu vermeiden --line-gepuffert auf einem Schwanz in einer ähnlichen Situation wie die OP und Kobis Lösung funktioniert gut für mich. In meinem Fall ausgeschlossen Zeilen mit entweder "Bot" oder "Spinne", während "/" (für mein Root-Dokument).

Meine ursprüngliche Befehl:

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

wird jetzt (mit "-P" perl-Schalter):

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