วิธีจับคู่“ อักขระใด ๆ ” ในนิพจน์ทั่วไปได้อย่างไร


304

ควรจับคู่ต่อไปนี้:

AAA123
ABCDEFGH123
XXXX123

ฉันสามารถทำได้: ".*123"?


2
ลิงก์นี้แสดงวิธีการที่ใช้งานได้ -> [^] + ซึ่งหมายความว่า 'ไม่ตรงกับตัวอักษร' ซึ่งเป็นค่าลบสองเท่าที่สามารถอ่านได้อีกครั้งว่าเป็น 'จับคู่อักขระใด ๆ ' แหล่งที่มา - loune.net/2011/02/ …
HockeyJ

คำตอบ:


643

ใช่คุณสามารถ. ว่าควรจะทำงาน

  • . ตัวอักษรใด ๆ
  • \. = อักขระจุดจริง
  • .?= .{0,1}= จับคู่อักขระศูนย์หรือหนึ่งครั้ง
  • .*= .{0,}= จับคู่อักขระถ่านศูนย์หรือมากกว่านั้น
  • .+= .{1,}= จับคู่ถ่านหนึ่งหรือหลายครั้ง

22
ไม่เสมอจุดหมายถึงถ่านใด ๆ ข้อยกเว้นเมื่อโหมดบรรทัดเดียว \ p {all} ควรเป็น
อังคาร

คุณจะรวมเครื่องหมายสแลชย้อนหลังลงในรายการตัวละครนี้ได้อย่างไร
ผลลัพธ์การค้นหาเว็บผลลัพธ์ Pi

1
@pippilongstocking Slash Backward คือ `\\ '
Poutrathor

58

ใช่ว่าใช้งานได้ แต่โปรดทราบว่า.จะไม่ตรงกับบรรทัดใหม่ยกเว้นว่าคุณผ่านการตั้งค่าสถานะDOTALLเมื่อรวบรวมนิพจน์:

Pattern pattern = Pattern.compile(".*123", Pattern.DOTALL);
Matcher matcher = pattern.matcher(inputStr);
boolean matchFound = matcher.matches();

11
นั่นคือข้อมูลที่มีประโยชน์มาก! ฉันคิดว่า.จะจับคู่บรรทัดใหม่ ฉันดีใจที่ฉันอ่านคำตอบของคุณฉันต้องใช้มัน!
Ben Kane

บางครั้งคุณอาจต้องจับคู่บรรทัดใหม่ใน Java regexes ในบริบทที่คุณไม่สามารถส่ง Pattern.DOTALL เช่นเมื่อทำการค้นหาหลายบรรทัด regex ใน Eclipse หรือเป็นผู้ใช้ของแอปพลิเคชัน Java ที่ให้การค้นหา regex ตามคำแนะนำของ regular-expression.infoคุณอาจต้องใช้{.,\n,\r,\u2028,\u2029,\u0085}เพื่อจับคู่อักขระใด ๆ (อักขระ Unicode เป็นอักขระที่ลงท้ายด้วยบรรทัดเพิ่มเติมที่ไม่ได้จับคู่กับ.ใน Java) แต่{.,\n,\r}จะใช้ได้กับไฟล์ข้อความส่วนใหญ่
Theodore Murdock

8
@TheodoreMurdock [\s\S]เป็นวิธียอดนิยมในการจับคู่อักขระใด ๆ หากคุณไม่สามารถใช้ DOTALL ได้
mpen

ในกรณีที่มันจะเข้ามาในใจของคุณไม่ได้ใช้(?:.|\\v)*เพราะJDK-6337993
Olivier Cailloux

22

ใช้รูปแบบ.เพื่อจับคู่อักขระใด ๆ หนึ่งครั้ง.*เพื่อจับคู่อักขระใด ๆ ที่เป็นศูนย์หรือมากกว่านั้น .+เพื่อจับคู่อักขระใด ๆ หนึ่งครั้งขึ้นไป


11

มีเครื่องมือทดสอบและพัฒนา regex ที่ซับซ้อนมากมาย แต่ถ้าคุณต้องการใช้ชุดทดสอบอย่างง่ายใน Java ต่อไปนี้เป็นสิ่งที่คุณสามารถเล่นกับ:

    String[] tests = {
        "AAA123",
        "ABCDEFGH123",
        "XXXX123",
        "XYZ123ABC",
        "123123",
        "X123",
        "123",
    };
    for (String test : tests) {
        System.out.println(test + " " +test.matches(".+123"));
    }

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

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


1
โหวตขึ้นเพียงเพื่อลิงค์ปกติ - แสดงออก. ข้อมูล เว็บไซต์ที่ยอดเยี่ยมสำหรับการเรียนรู้การแสดงออกปกติและสำหรับการอ้างอิง
Freiheit

9

ไม่*จะจับคู่กับอักขระศูนย์หรือมากกว่า คุณควรใช้+ซึ่งตรงกับหนึ่งหรือมากกว่าแทน

การแสดงออกนี้อาจทำงานได้ดีขึ้นสำหรับคุณ: [A-Z]+123


1
โหวตขึ้นที่นี่ OP ไม่ได้ระบุ แต่ดูเหมือนถูกต้องที่จะเพิ่มว่ารูปแบบจะตรงกับอักขระใด ๆ รวมถึงสิ่งต่าง ๆ เช่น ### 123, 123123,% $ # 123 ซึ่ง OP อาจไม่ต้องการ คลาสอักขระ @Huusom ใช้ด้านบน OP ทั้งหมดจะใช้เฉพาะอักขระตัวอักษรตัวพิมพ์ใหญ่ซึ่งอาจเป็นเจตนา
techdude

9

วิธีที่พบมากที่สุดที่ฉันเคยเห็นในการเข้ารหัสนี้คือคลาสอักขระที่สมาชิกสร้างพาร์ติชันของชุดอักขระที่เป็นไปได้ทั้งหมด

คนมักจะเขียนว่าเป็น[\s\S](ช่องว่างหรือไม่ว่าง) แม้[\w\W], [\d\D]ฯลฯ จะทำงานทั้งหมด


2
สำหรับการอ้างอิงจากregular-expressions.info/dot.html : "JavaScript และ VBScript ไม่มีตัวเลือกในการสร้างอักขระตัวแบ่งบรรทัดที่ตรงกับจุดในภาษาเหล่านั้นคุณสามารถใช้คลาสอักขระเช่น [\ s \ S] เพื่อจับคู่อักขระใด ๆ อักขระนี้จับคู่อักขระที่เป็นอักขระช่องว่าง (รวมถึงอักขระตัวแบ่งบรรทัด) หรืออักขระที่ไม่ใช่อักขระช่องว่างเนื่องจากอักขระทั้งหมดเป็นช่องว่างหรือไม่ใช่ช่องว่างคลาสอักขระนี้จึงจับคู่อักขระใด ๆ ."
คณบดีหรือ

7

.*และ.+สำหรับตัวอักษรใด ๆ ยกเว้นบรรทัดใหม่

การหลบหนีสองครั้ง

ในกรณีที่คุณต้องการรวมบรรทัดใหม่นิพจน์ต่อไปนี้อาจใช้ได้กับภาษาเหล่านั้นที่จำเป็นต้องใช้การหลบหลีกสองครั้งเช่น Java หรือ C ++:

[\\s\\S]*
[\\d\\D]*
[\\w\\W]*

สำหรับศูนย์หรือมากกว่านั้นหรือ

[\\s\\S]+
[\\d\\D]+
[\\w\\W]+

หนึ่งครั้งขึ้นไป

หนีเดี่ยว:

ไม่จำเป็นต้องใช้การ Escape ซ้ำสองครั้งสำหรับบางภาษาเช่น, C #, PHP, Ruby, PERL, Python, JavaScript:

[\s\S]*
[\d\D]*
[\w\W]*
[\s\S]+
[\d\D]+
[\w\W]+

ทดสอบ

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex_1 = "[\\s\\S]*";
        final String regex_2 = "[\\d\\D]*";
        final String regex_3 = "[\\w\\W]*";
        final String string = "AAA123\n\t"
             + "ABCDEFGH123\n\t"
             + "XXXX123\n\t";

        final Pattern pattern_1 = Pattern.compile(regex_1);
        final Pattern pattern_2 = Pattern.compile(regex_2);
        final Pattern pattern_3 = Pattern.compile(regex_3);

        final Matcher matcher_1 = pattern_1.matcher(string);
        final Matcher matcher_2 = pattern_2.matcher(string);
        final Matcher matcher_3 = pattern_3.matcher(string);

        if (matcher_1.find()) {
            System.out.println("Full Match for Expression 1: " + matcher_1.group(0));
        }

        if (matcher_2.find()) {
            System.out.println("Full Match for Expression 2: " + matcher_2.group(0));
        }
        if (matcher_3.find()) {
            System.out.println("Full Match for Expression 3: " + matcher_3.group(0));
        }
    }
}

เอาท์พุต

Full Match for Expression 1: AAA123
    ABCDEFGH123
    XXXX123

Full Match for Expression 2: AAA123
    ABCDEFGH123
    XXXX123

Full Match for Expression 3: AAA123
    ABCDEFGH123
    XXXX123

หากคุณต้องการที่จะสำรวจการแสดงออกจะได้รับการอธิบายบนแผงด้านบนขวาของregex101.com หากคุณต้องการคุณยังสามารถดูในลิงค์นี้ว่ามันจะตรงกับอินพุตตัวอย่างบางส่วนได้อย่างไร


วงจร RegEx

jex.imเห็นภาพการแสดงออกปกติ:

ป้อนคำอธิบายรูปภาพที่นี่


1
นั่นไม่ใช่คำตอบที่นี่ใช่ไหม stackoverflow.com/a/55149095/5424988
นกตัวที่สี่

ฉันชอบ(\W|\w)*แทนที่จะหลบหนีสองเท่า
Sudip Bhattarai

1
การอธิบายที่เป็นประโยชน์จริงๆ
Nagibaba

5

วิธีแก้ไขปัญหาเฉพาะสำหรับตัวอย่าง: -

ลอง[A-Z]*123$จะตรง123, ,AAA123 ASDFRRF123ในกรณีที่คุณต้องไม่น้อยกว่าตัวละครก่อนที่จะใช้งาน123[A-Z]+123$

โซลูชันทั่วไปสำหรับคำถาม (วิธีจับคู่ "อักขระใด ๆ " ในนิพจน์ทั่วไป):

  1. [\w|\W]{min_char_to_match,}หากคุณกำลังมองหาอะไรรวมถึงช่องว่างที่คุณสามารถลอง
  2. [\S]{min_char_to_match,}ถ้าคุณกำลังพยายามที่จะตรงกับอะไรยกเว้นช่องว่างที่คุณสามารถลอง

2

[^]ควรตรงกับตัวละครใด ๆ รวมถึงการขึ้นบรรทัดใหม่ [^CHARS]ตรงกับตัวละครทุกตัวยกเว้นสำหรับผู้ที่อยู่ในCHARS ถ้าCHARSว่างเปล่ามันตรงกับตัวละครทุกตัว

ตัวอย่าง JavaScript:

/a[^]*Z/.test("abcxyz \0\r\n\t012789ABCXYZ") // Returns ‘true’.

คุณจะช่วยเพิ่มรหัสเพื่อแจ้งให้เราทราบสิ่งที่คุณได้ลอง?
Jennis Vaishnav


-4

ฉันทำงานนี้จุดไม่เสมอหมายถึงอักขระใด ๆ ข้อยกเว้นเมื่อโหมดบรรทัดเดียว \p{all}ควรจะเป็น

String value = "|°¬<>!\"#$%&/()=?'\\¡¿/*-+_@[]^^{}";
String expression = "[a-zA-Z0-9\\p{all}]{0,50}";
if(value.matches(expression)){
    System.out.println("true");
} else {
    System.out.println("false");
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.