Regulärer Ausdruck für eine Zeichenfolge, die ein Wort enthält, aber kein anderes

103

Ich richte einige Ziele in Google Analytics ein und könnte eine kleine Regex-Hilfe gebrauchen.

Nehmen wir an, 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, der jede URL identifiziert, die den String selector = size enthält , aber NICHT details.cfm enthält

Ich weiß, dass ich diesen Ausdruck verwenden kann, um eine Zeichenfolge zu finden, die KEINE andere Zeichenfolge enthält:

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

Ich bin mir jedoch nicht sicher, wie ich den Teil selector = size hinzufügen soll .

Jede Hilfe wäre sehr dankbar!

Chris Stahl
quelle

Antworten:

144

Dies sollte es tun:

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

^.*selector=size.*$sollte klar genug sein. Das erste Bit (?!.*details.cfm)ist ein negativer Ausblick: Vor dem Abgleichen der Zeichenfolge wird überprüft, ob die Zeichenfolge keine "details.cfm" enthält (mit einer beliebigen Anzahl von Zeichen davor).

Kobi
quelle
8
Zu Ihrer Information , schauen Sie auf regexr.com nach, um diese Ausdrücke zu testen.
Joshua Pinter
Vergessen Sie immer negative Lookahead und es ist so nützlich
Alexei Blue
"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0ist falsch. (Beachten Sie, dass die Zeichenfolge enthält "...selector=sized...".) Warum auch .*$am Ende?
Cary Swoveland
4

Regex könnte sein (Perl-Syntax):

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/`
djipko
quelle
Dies ist eine beschädigte Regex. Die eckigen Klammern verwandeln alle Mustersequenzen in eine Kombination einzelner Zeichen.
Wiktor Stribiżew
2
^(?=.*selector=size)(?:(?!details\.cfm).)+$

Wenn Ihre Regex-Engine positive Quantifizierer unterstützt (obwohl ich vermute, dass Google Analytics dies nicht tut), ist dies bei großen Eingabesätzen wahrscheinlich besser:

^[^?]*+(?<!details\.cfm).*?selector=size.*$
Tomalak
quelle
Dies setzt voraus, dass selector=sizees immer vorher ist details.cfm, was in der letzten URL nicht der Fall ist.
Kobi
Nur um das zu klären, war ich es nicht. Ich kann nicht verstehen, warum jemand hier zwei Antworten herabgestimmt hat, beide sind richtig.
Kobi
@Kobi: Dies hätte ein Ausblick sein sollen, korrigiert. Oh und übrigens, ich ahnte nicht, dass es Ihre Ablehnung war.
Tomalak
0

Ich suchte nach einer Möglichkeit, --line-bufferedin einer ähnlichen Situation wie der OP zu vermeiden, und die Lösung von Kobi funktioniert für mich hervorragend. In meinem Fall das Ausschließen von Zeilen mit "Bot" oder "Spider" beim Einschließen ' / '(für mein Stammdokument).

Mein ursprünglicher Befehl:

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

Jetzt wird (mit -PPerl-Schalter):

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