นิพจน์ Regex ใน Java \\ s เทียบกับ \\ s +


คำตอบ:


91

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

Greedy quantifiers
X?  X, once or not at all
X*  X, zero or more times
X+  X, one or more times
X{n}    X, exactly n times
X{n,}   X, at least n times
X{n,m}  X, at least n but not more than m times

Reluctant quantifiers
X?? X, once or not at all
X*? X, zero or more times
X+? X, one or more times
X{n}?   X, exactly n times
X{n,}?  X, at least n times
X{n,m}? X, at least n but not more than m times

Possessive quantifiers
X?+ X, once or not at all
X*+ X, zero or more times
X++ X, one or more times
X{n}+   X, exactly n times
X{n,}+  X, at least n times
X{n,m}+ X, at least n but not more than m times

21
ฉันชอบวิธีการที่พวกเขาให้คำอธิบายแบบแยกกันของตัวบอกปริมาณแต่ละตัวที่โลภไม่เต็มใจและเป็นเจ้าของจากนั้นก็พูดในสิ่งที่เหมือนกันทุกประการเกี่ยวกับทั้งสาม ;)
Alan Moore

60

การreplaceAllเรียกทั้งสองจะให้ผลลัพธ์เหมือนกันเสมอไม่ว่าxจะเป็นอะไรก็ตาม อย่างไรก็ตามสิ่งสำคัญคือต้องสังเกตว่านิพจน์ทั่วไปทั้งสองไม่เหมือนกัน:

  • \\s - จับคู่อักขระช่องว่างเดียว
  • \\s+ - จับคู่ลำดับของอักขระเว้นวรรคหนึ่งตัวขึ้นไป

ในกรณีนี้จะไม่สร้างความแตกต่างเนื่องจากคุณกำลังแทนที่ทุกอย่างด้วยสตริงว่าง (แม้ว่าจะดีกว่าถ้าใช้\\s+จากมุมมองด้านประสิทธิภาพ) หากคุณแทนที่ด้วยสตริงที่ไม่ว่างเปล่าทั้งสองจะทำงานแตกต่างกัน


เขียนบรรทัดแรกของคุณถ้า x คือ "จองโดเมนของคุณและรับ \ n \ n \ n \ n \ n \ n ออนไลน์วันนี้" ทั้งสองอย่างจะให้ผลลัพธ์เหมือนกันหรือไม่?
sofs1

3
@ user3705478 ทั้งสองจะให้ผลลัพธ์เหมือนกันแม้ว่าจะมีช่องว่างหลายช่องต่อกันก็ตาม ความแตกต่างอยู่ที่วิธีจัดการ หากคุณจะมีกลุ่มของ (เช่น) 3 ช่องว่างต่อจากกันโดยตรง \\ s + ให้ใช้กลุ่มนั้นและเปลี่ยนทั้งหมดให้เป็น "" ในขณะที่ \\ s จะประมวลผลช่องว่างทั้งหมดด้วยตัวเอง
Dennie

11

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

อย่างไรก็ตามx.replaceAll("\\s+", "");จะเป็นวิธีที่มีประสิทธิภาพมากขึ้นในการตัดแต่งช่องว่าง (หากสตริงสามารถมีช่องว่างต่อเนื่องกันได้หลายช่อง) เนื่องจากอาจไม่มีการแทนที่น้อยกว่าเนื่องจาก regex \\s+จับคู่ช่องว่าง 1 ช่องหรือมากกว่าพร้อมกันและแทนที่ด้วยสตริงว่าง

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

x.replaceAll("\\s+", "");

2

regex แรกจะจับคู่อักขระเว้นวรรคหนึ่งตัว นิพจน์ที่สองจะจับคู่อักขระเว้นวรรคอย่างไม่เต็มใจ สำหรับวัตถุประสงค์ส่วนใหญ่ regexes ทั้งสองนี้มีความคล้ายคลึงกันมากยกเว้นในกรณีที่สอง regex สามารถจับคู่สตริงได้มากขึ้นหากป้องกันไม่ให้การจับคู่ regex ล้มเหลว จากhttp://www.coderanch.com/t/570917/java/java/regex-difference


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