ตัวอย่างเช่นฉันมีนิพจน์(ma|(t){1})
ทั่วไป มันตรงma
และไม่ตรงกับt
bla
ฉันต้องการที่จะลบล้าง regex จึงจะต้องตรงbla
และไม่ma
และt
, โดยการเพิ่มสิ่งที่จะ regex ฉันรู้ว่าฉันเขียนbla
ได้ regex ที่แท้จริงนั้นซับซ้อนกว่าอย่างไรก็ตาม
ตัวอย่างเช่นฉันมีนิพจน์(ma|(t){1})
ทั่วไป มันตรงma
และไม่ตรงกับt
bla
ฉันต้องการที่จะลบล้าง regex จึงจะต้องตรงbla
และไม่ma
และt
, โดยการเพิ่มสิ่งที่จะ regex ฉันรู้ว่าฉันเขียนbla
ได้ regex ที่แท้จริงนั้นซับซ้อนกว่าอย่างไรก็ตาม
คำตอบ:
ใช้การมองหาเชิงลบ: (?!
pattern
)
การมองหาเชิงบวกสามารถใช้เพื่อยืนยันว่ารูปแบบนั้นตรงกัน การมองหาเชิงลบนั้นตรงกันข้าม: ใช้เพื่อยืนยันว่ารูปแบบไม่ตรงกัน รสชาติบางอย่างรองรับการยืนยัน บางข้อ จำกัด ในการมองหลัง ฯลฯ
นี่คือความพยายามที่จะหาวิธีแก้ปัญหาของ regex สำหรับปัญหาของเล่นเป็นแบบฝึกหัด พวกเขาควรให้ความรู้หากคุณพยายามเรียนรู้วิธีต่างๆที่คุณสามารถใช้การมองหา (การวางซ้อนใช้เพื่อจับภาพ ฯลฯ ):
grep
.
Pattern.compile("(?!(a.*b))").matcher("xab").matches()
ควรจะเป็นtrue
ใช่ไหม?
สมมติว่าคุณต้องการเพียงไม่อนุญาตให้ใช้สตริงที่ตรงกับ regex โดยสมบูรณ์ (เช่นใช้ได้mmbla
แต่mm
ไม่ใช่) นี่คือสิ่งที่คุณต้องการ:
^(?!(?:m{2}|t)$).*$
(?!(?:m{2}|t)$)
เป็นเชิงลบlookahead ; มีข้อความว่า "เริ่มจากตำแหน่งปัจจุบันอักขระสองสามตัวถัดไปไม่ใช่ mm
หรือt
ตามด้วยท้ายสตริง" จุดยึดเริ่มต้น ( ^
) ที่จุดเริ่มต้นช่วยให้แน่ใจว่ามีการใช้ lookahead ที่จุดเริ่มต้นของสตริง หากประสบความสำเร็จการ.*
ดำเนินการต่อและใช้สตริง
FYI หากคุณใช้matches()
วิธีการของ Java คุณไม่จำเป็นต้อง^
ใช้ขั้นตอนสุดท้ายและขั้นสุดท้าย$
แต่ก็ไม่ได้ทำอันตรายใด ๆ $
ภายใน lookahead จะต้องแม้ว่า
.*
ที่ส่วนท้ายของ regex มิฉะนั้นจะปฏิเสธทุกสตริง
$
ภายใน lookahead เชิงลบและ.*
ในตอนท้ายมีทั้งบิตที่สำคัญ เช่นเคยกับ REs ชุดการทดสอบหน่วยที่แข็งแกร่งมีความสำคัญอย่างยิ่งในการทำให้ถูกต้อง คำตอบนี้ถูกต้อง 100%
\b(?=\w)(?!(ma|(t){1}))\b(\w*)
นี่คือ regex ที่กำหนด
\ b คือการค้นหาขอบเขตของคำ
มองไปข้างหน้าในเชิงบวก (? = \ w) อยู่ที่นี่เพื่อหลีกเลี่ยงช่องว่าง
การมองไปข้างหน้าในแง่ลบมากกว่า regex ดั้งเดิมคือการป้องกันไม่ให้ตรงกัน
และสุดท้าย (\ w *) คือการจับทุกคำที่เหลือ
กลุ่มที่จะเก็บคำคือกลุ่มที่ 3
(?! รูปแบบ) จะไม่ทำงานเนื่องจากสตริงย่อยใด ๆ จะตรง
กับแบบง่าย ^ (?! (?: m {2} | t) $) * $ will ไม่ทำงานเนื่องจากรายละเอียดเป็นแบบเต็มบรรทัด
ใช้สิ่งนี้หากคุณใช้ laravel
Laravel มี not_regex โดยที่ฟิลด์ภายใต้การตรวจสอบต้องไม่ตรงกับนิพจน์ทั่วไปที่กำหนด ใช้preg_match
ฟังก์ชันPHP ภายใน
'email' => 'not_regex:/^.+$/i'
{1}
ก็ไร้ประโยชน์อย่างสิ้นเชิง (ถ้าคุณคิดว่ามันให้คุณค่าทำไมคุณไม่เขียน((m{1}a{1}){1}|(t){1}){1}
ล่ะ)