นิพจน์ทั่วไปสำหรับสตริงที่มีหนึ่งคำ แต่ไม่ใช่อีกคำ


105

ฉันกำลังตั้งเป้าหมายบางอย่างใน Google Analytics และสามารถใช้ความช่วยเหลือเกี่ยวกับ regex ได้เล็กน้อย

สมมติว่าฉันมี URL 4 รายการ

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

ฉันต้องการสร้างนิพจน์ที่จะระบุ URL ใด ๆ ที่มี string selector = sizeแต่ไม่มีdetails.cfm

ฉันรู้ว่าในการค้นหาสตริงที่ไม่มีสตริงอื่นฉันสามารถใช้นิพจน์นี้:

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

แต่ฉันไม่แน่ใจว่าจะเพิ่มในส่วนselector = sizeอย่างไร

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก!

คำตอบ:


146

สิ่งนี้ควรทำ:

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

^.*selector=size.*$ควรมีความชัดเจนเพียงพอ บิตแรก(?!.*details.cfm)เป็นการมองไปข้างหน้าเชิงลบ: ก่อนที่จะจับคู่สตริงจะตรวจสอบว่าสตริงไม่มี "details.cfm" (โดยมีอักขระจำนวนเท่าใดก็ได้)


8
FYI ลองดูregexr.comเพื่อดูวิธีที่ดีในการทดสอบนิพจน์เหล่านี้
Joshua Pinter

ลืมมองโลกในแง่ลบเสมอและมันมีประโยชน์มาก
Alexei Blue

"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0ไม่ถูกต้อง (หมายเหตุสตริงประกอบด้วย"...selector=sized...") นอกจากนี้ทำไม.*$ในตอนท้าย?
Cary Swoveland

4

regex อาจเป็น (ไวยากรณ์ perl):

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

นี่คือ regex ที่เสียหายวงเล็บเหลี่ยมจะเปลี่ยนลำดับรูปแบบทั้งหมดเป็นการรวมกันของแต่ละตัวอักษร
Wiktor Stribiżew

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

หากเอ็นจิ้น regex ของคุณรองรับตัวบ่งชี้เชิงบวก (แม้ว่าฉันสงสัยว่า Google Analytics ไม่มี) ฉันเดาว่าสิ่งนี้จะทำงานได้ดีกว่าสำหรับชุดอินพุตขนาดใหญ่:

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

สิ่งนี้จะถือว่าselector=sizeมาก่อนเสมอdetails.cfmซึ่งไม่ใช่กรณีใน url สุดท้าย
Kobi

เพียงเพื่อที่จะเคลียร์สิ่งนี้มันไม่ใช่ฉัน ฉันไม่เห็นว่าทำไมใครบางคนถึงลงคะแนนสองคำตอบที่นี่พวกเขาถูกต้องทั้งคู่
Kobi

@ Kobi: สิ่งนี้ควรได้รับการแก้ไขล่วงหน้า โอ้และฉันไม่สงสัยเลยว่านี่เป็นการลงคะแนนเสียงของคุณ
Tomalak

0

ฉันกำลังมองหาวิธีที่จะหลีกเลี่ยง--line-bufferedในสถานการณ์ที่คล้ายคลึงกันเนื่องจากวิธีการแก้ปัญหาของ OP และ Kobi ทำงานได้ดีสำหรับฉัน ในกรณีของฉันไม่รวมบรรทัดที่มี "บอท" หรือ "สไปเดอร์" ในขณะที่รวม' / '(สำหรับเอกสารรูทของฉัน)

คำสั่งเดิมของฉัน:

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

ตอนนี้กลายเป็น (พร้อม-Pสวิตช์ perl):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.