Ekspresi reguler untuk string yang berisi satu kata tetapi tidak kata lainnya

103

Saya sedang menyiapkan beberapa sasaran di Google Analytics dan dapat menggunakan sedikit bantuan regex.

Katakanlah saya memiliki 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

Saya ingin membuat ekspresi yang akan mengidentifikasi URL apa pun yang berisi string selector = size tetapi TIDAK berisi details.cfm

Saya tahu bahwa untuk menemukan string yang TIDAK berisi string lain, saya dapat menggunakan ungkapan ini:

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

Tapi, saya tidak yakin bagaimana menambahkan bagian selector = size .

Bantuan apa pun akan sangat dihargai!

Chris Stahl
sumber

Jawaban:

144

Ini harus melakukannya:

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

^.*selector=size.*$harus cukup jelas. Bit pertama, (?!.*details.cfm)adalah pandangan ke depan negatif: sebelum mencocokkan string itu memeriksa bahwa string tidak mengandung "details.cfm" (dengan sejumlah karakter sebelumnya).

Kobi
sumber
8
FYI, periksa regexr.com untuk cara yang bagus untuk menguji ekspresi ini.
Joshua Pinter
Selalu lupakan tentang pandangan negatif dan ini sangat berguna
Alexei Blue
"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0salah. (Perhatikan string berisi "...selector=sized...".) Juga, mengapa .*$di akhir?
Cary Swoveland
4

regex bisa jadi (sintaks perl):

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/`
djipko
sumber
Ini adalah regex yang rusak, tanda kurung siku mengubah semua urutan pola menjadi kombinasi karakter individual.
Wiktor Stribiżew
2
^(?=.*selector=size)(?:(?!details\.cfm).)+$

Jika mesin regex Anda mendukung pengukur posesif (meskipun saya curiga Google Analytics tidak), saya rasa ini akan bekerja lebih baik untuk kumpulan masukan yang besar:

^[^?]*+(?<!details\.cfm).*?selector=size.*$
Tomalak
sumber
Ini mengasumsikan selector=sizeselalu sebelumnya details.cfm, yang tidak terjadi di url terakhir.
Kobi
Hanya untuk menjernihkan ini, bukan aku. Saya tidak bisa melihat mengapa seseorang akan memilih dua jawaban di sini, keduanya benar.
Kobi
@Kobi: Ini seharusnya melihat ke depan, dikoreksi. Oh, dan omong-omong, saya tidak curiga itu adalah suara negatif Anda.
Tomalak
0

Saya sedang mencari cara untuk menghindari --line-bufferedekor dalam situasi yang sama karena solusi OP dan Kobi bekerja sangat baik untuk saya. Dalam kasus saya tidak termasuk baris dengan "bot" atau "spider" sementara menyertakan ' / '(untuk dokumen root saya).

Perintah asli saya:

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

Sekarang menjadi (dengan -Psaklar perl):

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