จะลบล้าง regex ทั้งหมดได้อย่างไร?


97

ตัวอย่างเช่นฉันมีนิพจน์(ma|(t){1})ทั่วไป มันตรงmaและไม่ตรงกับtbla

ฉันต้องการที่จะลบล้าง regex จึงจะต้องตรงblaและไม่maและt, โดยการเพิ่มสิ่งที่จะ regex ฉันรู้ว่าฉันเขียนblaได้ regex ที่แท้จริงนั้นซับซ้อนกว่าอย่างไรก็ตาม


5
นอกเหนือจากนั้น{1}ก็ไร้ประโยชน์อย่างสิ้นเชิง (ถ้าคุณคิดว่ามันให้คุณค่าทำไมคุณไม่เขียน((m{1}a{1}){1}|(t){1}){1}ล่ะ)
tripleee

คำตอบ:


103

ใช้การมองหาเชิงลบ: (?!pattern)

การมองหาเชิงบวกสามารถใช้เพื่อยืนยันว่ารูปแบบนั้นตรงกัน การมองหาเชิงลบนั้นตรงกันข้าม: ใช้เพื่อยืนยันว่ารูปแบบไม่ตรงกัน รสชาติบางอย่างรองรับการยืนยัน บางข้อ จำกัด ในการมองหลัง ฯลฯ

ลิงค์ไปยัง regular-expressions.info

ดูสิ่งนี้ด้วย

ตัวอย่างเพิ่มเติม

นี่คือความพยายามที่จะหาวิธีแก้ปัญหาของ regex สำหรับปัญหาของเล่นเป็นแบบฝึกหัด พวกเขาควรให้ความรู้หากคุณพยายามเรียนรู้วิธีต่างๆที่คุณสามารถใช้การมองหา (การวางซ้อนใช้เพื่อจับภาพ ฯลฯ ):


2
Regular-expressions.info เป็นแหล่งข้อมูลที่ดีสำหรับ regex ทุกสิ่ง
Freiheit

มีอะไรรองรับLookaroundบ้าง? ใช้ไม่ได้กับgrep.
Lazer

Pattern.compile("(?!(a.*b))").matcher("xab").matches()ควรจะเป็นtrueใช่ไหม?
Karl Richter

4
ดูเหมือนว่าจะไม่ถูกต้องโปรดดูstackoverflow.com/questions/8610743/…สำหรับทางเลือกที่ถูกต้อง
Karl Richter

57

สมมติว่าคุณต้องการเพียงไม่อนุญาตให้ใช้สตริงที่ตรงกับ regex โดยสมบูรณ์ (เช่นใช้ได้mmblaแต่mmไม่ใช่) นี่คือสิ่งที่คุณต้องการ:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)เป็นเชิงลบlookahead ; มีข้อความว่า "เริ่มจากตำแหน่งปัจจุบันอักขระสองสามตัวถัดไปไม่ใช่ mmหรือtตามด้วยท้ายสตริง" จุดยึดเริ่มต้น ( ^) ที่จุดเริ่มต้นช่วยให้แน่ใจว่ามีการใช้ lookahead ที่จุดเริ่มต้นของสตริง หากประสบความสำเร็จการ.*ดำเนินการต่อและใช้สตริง

FYI หากคุณใช้matches()วิธีการของ Java คุณไม่จำเป็นต้อง^ใช้ขั้นตอนสุดท้ายและขั้นสุดท้าย$แต่ก็ไม่ได้ทำอันตรายใด ๆ $ภายใน lookahead จะต้องแม้ว่า


2
ส่วนที่เป็นประโยชน์ที่สุดของคำตอบนี้คือคุณต้องเพิ่ม.*ที่ส่วนท้ายของ regex มิฉะนั้นจะปฏิเสธทุกสตริง
Rav

2
$ ภายใน lookahead เชิงลบและ.*ในตอนท้ายมีทั้งบิตที่สำคัญ เช่นเคยกับ REs ชุดการทดสอบหน่วยที่แข็งแกร่งมีความสำคัญอย่างยิ่งในการทำให้ถูกต้อง คำตอบนี้ถูกต้อง 100%
Tom Dibble

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

นี่คือ regex ที่กำหนด
\ b คือการค้นหาขอบเขตของคำ
มองไปข้างหน้าในเชิงบวก (? = \ w) อยู่ที่นี่เพื่อหลีกเลี่ยงช่องว่าง
การมองไปข้างหน้าในแง่ลบมากกว่า regex ดั้งเดิมคือการป้องกันไม่ให้ตรงกัน
และสุดท้าย (\ w *) คือการจับทุกคำที่เหลือ
กลุ่มที่จะเก็บคำคือกลุ่มที่ 3
(?! รูปแบบ) จะไม่ทำงานเนื่องจากสตริงย่อยใด ๆ จะตรง
กับแบบง่าย ^ (?! (?: m {2} | t) $) * $ will ไม่ทำงานเนื่องจากรายละเอียดเป็นแบบเต็มบรรทัด


0

ใช้สิ่งนี้หากคุณใช้ laravel

Laravel มี not_regex โดยที่ฟิลด์ภายใต้การตรวจสอบต้องไม่ตรงกับนิพจน์ทั่วไปที่กำหนด ใช้preg_matchฟังก์ชันPHP ภายใน

'email' => 'not_regex:/^.+$/i'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.