Java RegEx ไม่คำนึงถึงขนาดตัวพิมพ์หรือไม่


111

ใน Java เมื่อทำการแทนที่ทั้งหมดเพื่อค้นหารูปแบบ regex เช่น:

replaceAll("\\?i\\b(\\w+)\\b(\\s+\\1)+\\b", "$1"); 

(หากต้องการลบคำที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ที่ซ้ำกันเช่น Test test) ฉันไม่แน่ใจว่าฉันใส่ไฟล์?i. ฉันอ่านว่ามันควรจะอยู่ที่จุดเริ่มต้น แต่ถ้าฉันเอาออกฉันก็จะจับคำที่ซ้ำกันติดต่อกัน (เช่น test test) แต่ไม่ใช่คำที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ (เช่น Test test) ฉันเลยคิดว่าจะเพิ่ม? i ในตอนแรก แต่ดูเหมือนจะไม่ได้งานทำ ความคิดใด ๆ ? ขอบคุณ!


ลองดูที่stackoverflow.com/a/55980176/3593084
Mr.Q

คำตอบ:


119

RegexBuddyกำลังบอกฉันว่าคุณต้องการรวมไว้ที่จุดเริ่มต้นหรือไม่นี่คือไวยากรณ์ที่ถูกต้อง:

"(?i)\\b(\\w+)\\b(\\s+\\1)+\\b"

168

คุณยังสามารถจับคู่ regex ที่ไม่คำนึงถึงขนาดตัวพิมพ์และทำให้อ่านได้ง่ายขึ้นโดยใช้ค่าคงที่ Pattern.CASE_INSENSITIVE เช่น:

Pattern mypattern = Pattern.compile(MYREGEX, Pattern.CASE_INSENSITIVE);
Matcher mymatcher= mypattern.matcher(mystring);

2
อืม .... รวมบิตหรือการดำเนินการ ...Pattern.compile(myregex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE)
Nick Grealy

4
สิ่งนี้สามารถอ่านได้มากกว่า(?i)สิ่งนี้regexes Java นั้นอ่านไม่ได้แล้ว: S
Bartek Banachewicz

นี่เป็นคำตอบเดียวกับคำตอบของ relet เมื่อ 4 ปีก่อน แต่ได้รับการโหวตทั้งหมด แปลก
Zoomzoom

@Zoomzoom มันไม่ใช่ตอนที่ฉันเขียน :) ถ้าคุณตรวจสอบประวัติฉบับของ relet คุณจะเห็นว่ามันเปลี่ยนไปในปี 2018 stackoverflow.com/posts/3436124/…
Christian Vielma

126

ใช่สามารถเปิดใช้งานและปิดใช้งานตัวพิมพ์เล็กและใหญ่ได้ตามต้องการใน Java regex

ดูเหมือนว่าคุณต้องการสิ่งนี้:

    System.out.println(
        "Have a meRry MErrY Christmas ho Ho hO"
            .replaceAll("(?i)\\b(\\w+)(\\s+\\1)+\\b", "$1")
    );
    // Have a meRry Christmas ho

โปรดทราบว่าฝัง Pattern.CASE_INSENSITIVEธงไม่ได้(?i) \?iโปรดทราบว่า\bมีการลบหนึ่งส่วนที่ไม่จำเป็นออกจากรูปแบบ

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

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

เพื่อแสดงให้เห็นที่นี่เป็นตัวอย่างของการยุบวิ่งของตัวอักษรเช่นที่คล้ายกันเพียงแค่"AaAaaA""A"

    System.out.println(
        "AaAaaA eeEeeE IiiIi OoooOo uuUuUuu"
            .replaceAll("(?i)\\b([A-Z])\\1+\\b", "$1")
    ); // A e I O u

ตอนนี้สมมติว่าเราระบุว่าการรันควรถูกยุบก็ต่อเมื่อเริ่มต้นด้วยตัวอักษรตัวพิมพ์ใหญ่ จากนั้นเราต้องวาง(?i)ในที่ที่เหมาะสม:

    System.out.println(
        "AaAaaA eeEeeE IiiIi OoooOo uuUuUuu"
            .replaceAll("\\b([A-Z])(?i)\\1+\\b", "$1")
    ); // A eeEeeE I O uuUuUuu

โดยทั่วไปคุณสามารถเปิดและปิดการตั้งค่าสถานะใดก็ได้ภายในรูปแบบตามที่คุณต้องการ

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

  • java.util.regex.Pattern
  • regular-expressions.info/Modifiers
    • การระบุโหมดภายในนิพจน์ทั่วไป
      • แทนที่จะเป็น/regex/i( Pattern.CASE_INSENSITIVEใน Java) คุณสามารถทำได้/(?i)regex/
    • การเปิดและปิดโหมดเฉพาะบางส่วนของนิพจน์ทั่วไป
      • คุณยังสามารถทำได้ /first(?i)second(?-i)third/
    • ช่วงการปรับเปลี่ยน
      • คุณยังสามารถทำได้ /first(?i:second)third/
  • regular-expressions.info/Word Boundaries (มีเสมอ\bระหว่าง a \wและ a \s)

คำถามที่เกี่ยวข้อง


36

หากนิพจน์ทั้งหมดของคุณไม่คำนึงถึงขนาดตัวพิมพ์คุณสามารถระบุCASE_INSENSITIVEแฟล็ก:

Pattern.compile(regexp, Pattern.CASE_INSENSITIVE)

ขอบคุณสำหรับคำตอบ. นี่คือสิ่งที่ฉันกำลังมองหา ใน python เรามี re.IGNORECASE กำลังมองหาคำตอบที่คล้ายกันใน JAVA
Doogle

1

คุณยังสามารถนำสตริงเริ่มต้นของคุณซึ่งคุณจะตรวจสอบการจับคู่รูปแบบเป็นตัวพิมพ์เล็ก และใช้ในรูปแบบสัญลักษณ์ตัวพิมพ์เล็กของคุณตามลำดับ

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