คุณสามารถสร้างเพียงส่วนหนึ่งของ regex case-insensitive ได้ไหม


102

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

ตัวอย่างเช่นสมมติว่าฉันมีสตริงดังนี้:

fooFOOfOoFoOBARBARbarbarbAr

จะเกิดอะไรขึ้นหากฉันต้องการจับคู่ "foo" ที่เกิดขึ้นทั้งหมดไม่ว่าจะเป็นกรณีใด แต่ฉันต้องการจับคู่ "BAR" ตัวพิมพ์ใหญ่เท่านั้น

ทางออกที่ดีคือสิ่งที่ใช้ได้กับรสชาติ regex แต่ฉันสนใจที่จะฟังภาษาที่เฉพาะเจาะจงเช่นกัน (ขอบคุณEspo )

แก้ไข

ลิงค์ที่ Espo ให้มานั้นมีประโยชน์มาก มีตัวอย่างที่ดีเกี่ยวกับการเปิดและปิดตัวปรับแต่งภายในนิพจน์

สำหรับตัวอย่างที่สร้างขึ้นของฉันฉันสามารถทำสิ่งนี้ได้:

(?i)foo*(?-i)|BAR

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

ดูเหมือนว่าจะใช้ได้กับการใช้งาน regex ส่วนใหญ่ยกเว้น Javascript, Python และอื่น ๆ อีกสองสามอย่าง (ตามที่ Espo กล่าวถึง)

เรื่องใหญ่ที่ฉันสงสัยเกี่ยวกับ (Perl, PHP, .NET) รองรับการเปลี่ยนแปลงโหมดอินไลน์ทั้งหมด


คำถามนี้ได้ถูกเพิ่มเข้าไปในคำถามที่พบบ่อยเกี่ยวกับนิพจน์ทั่วไปของStack Overflowภายใต้ "ตัวปรับเปลี่ยน"
aliteralmind

คำตอบ:


88

Perl ช่วยให้คุณสามารถเป็นส่วนหนึ่งของนิพจน์ทั่วไปที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่โดยใช้ตัวปรับเปลี่ยนรูปแบบ (? i :)

รสชาติ regex สมัยใหม่ช่วยให้คุณสามารถใช้ตัวปรับแต่งกับเพียงบางส่วนของนิพจน์ทั่วไป หากคุณแทรกตัวปรับแต่ง (? ism) ตรงกลาง regex ตัวปรับแต่งจะใช้กับส่วนของ regex ทางด้านขวาของตัวปรับเปลี่ยนเท่านั้น คุณสามารถปิดโหมดได้โดยนำหน้าด้วยเครื่องหมายลบ โหมดทั้งหมดหลังจากเครื่องหมายลบจะถูกปิด เช่น (? i-sm) จะเปิดการไม่ไวต่อตัวพิมพ์และปิดทั้งโหมดบรรทัดเดียวและโหมดหลายบรรทัด

รสชาติ regex ทั้งหมดไม่รองรับสิ่งนี้ JavaScript และ Python ใช้ตัวปรับเปลี่ยนโหมดทั้งหมดกับนิพจน์ทั่วไปทั้งหมด พวกเขาไม่สนับสนุนไวยากรณ์ (? -ismx) เนื่องจากการปิดตัวเลือกจะไม่มีจุดหมายเมื่อตัวปรับโหมดใช้กับนิพจน์ทั่วไปทั้งหมด ตัวเลือกทั้งหมดจะปิดโดยค่าเริ่มต้น

คุณสามารถทดสอบได้อย่างรวดเร็วว่ารสชาติ regex ที่คุณใช้จัดการกับตัวปรับแต่งโหมดอย่างไร regex (? i) te (? - i) st ควรตรงกับการทดสอบและ TEst แต่ไม่ใช่ teST หรือ TEST

ที่มา


6

คุณใช้ภาษาอะไร วิธีมาตรฐานในการทำเช่นนี้จะเป็นเช่น / ([Ff] [Oo] {2} | BAR) / โดยเปิดความไวของตัวพิมพ์เล็กและใหญ่ แต่ใน Java มีตัวปรับความไวของตัวพิมพ์ (? i) ซึ่งทำให้ทั้งหมด อักขระทางด้านขวาของมันไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ (? -i) ซึ่งบังคับให้เกิดความอ่อนไหว ตัวอย่างของการที่ Java regex ปรับปรุงสามารถพบได้ที่นี่


+1 ทำไมต้องรำคาญทำให้มันไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่เมื่อคุณสามารถจับคู่ทั้งสองกรณีได้
Nona Urbiz

12
@NonaUrbiz: เพราะสำนวน(?i)foobarน่าอ่านกว่า[Ff][Oo]{2}[Bb][Aa][Rr]
Thanatos

1
และเพราะมันสามารถเจริญเติบโตได้วิธีที่มีขนดกมากขึ้นและมีความซับซ้อน
สับ

6

น่าเสียดายที่ไวยากรณ์สำหรับการจับคู่แบบไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ไม่ใช่เรื่องธรรมดา ใน. NET คุณสามารถใช้แฟล็ก RegexOptions.IgnoreCase หรือ? i modifier


5

เป็นความจริงเราสามารถพึ่งพาตัวปรับแต่งแบบอินไลน์ตามที่อธิบายไว้ในการเปิดและปิดโหมดสำหรับเฉพาะบางส่วนของนิพจน์ทั่วไป :

regex (?i)te(?-i)stควรจะตรงกับการทดสอบและการTEstแต่ไม่ได้หรือteSTTEST

อย่างไรก็ตามคุณลักษณะที่รองรับอีกเล็กน้อยคือ(?i:...)กลุ่มตัวปรับแต่งแบบอินไลน์ (ดูช่วงของตัวปรับแต่ง ) ไวยากรณ์คือ(?i:รูปแบบที่คุณต้องการทำให้ cas-insensitive และตามด้วย a ).

(?i:foo)|BAR

ย้อนกลับ : หากรูปแบบของคุณจะรวบรวมกับตัวเลือกที่ตายและกรณีที่คุณต้องทำให้ส่วนหนึ่งของกรณี regex ไวคุณเพิ่ม-หลังจากที่:?(?-i:...)

ตัวอย่างใช้ในภาษาต่างๆ (การตัดไม้ขีดไฟด้วยวงเล็บเหลี่ยม):

ไม่รองรับใน , , , std::regex, , .


ได้รับการสนับสนุนในbashถ้าใช้ regex "เหมือน Perl" ลอง:echo BAR | grep -P '(?i)bar'
Noam Manos

@NoamManos นั่นไม่ใช่ Bash ที่แท้จริงนั่นคือgrepและมันเกี่ยวข้องกับ PCRE ซึ่งเป็นไลบรารีนิพจน์ทั่วไปที่เข้ากันได้กับ Perl อยู่แล้วดังนั้นมันจึงถูกปกปิดในperlไฟล์. อย่างที่คุณเห็นฉันไม่ได้แสดงรายการgrepที่นี่เนื่องจากgrep -Pตัวเลือกไม่ได้รับการสนับสนุนในระดับสากล (รองรับโดย GNU เท่านั้นgrep)
Wiktor Stribiżew

4

คุณสามารถใช้

(?:F|f)(?:O|o)(?:O|o)

?: ในวงเล็บใน. Net หมายความว่าไม่ใช่การจับภาพและใช้เพื่อจัดกลุ่มเงื่อนไขของ | (หรือ) คำสั่ง


27
"[fF] [oO] [oO]" เป็นทางเลือกที่ดีกว่าไม่ใช่หรือ สำหรับตัวอย่างในมือคุณสามารถไปได้ไกลถึง "[fF] [oO] \ {2}" ;-)
Tomalak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.