การใช้วิธี Pattern.quote คืออะไร?

ฉันกำลังพยายามทำความเข้าใจ Pattern.quote โดยใช้โค้ดต่อไปนี้:

String pattern = Pattern.quote("1252343% 8 567 hdfg gf^$545");
System.out.println("Pattern is : "+pattern);

สร้างผลลัพธ์:

Pattern is : \Q1252343% 8 567 hdfg gf^$545\E

\Q และ \E ที่นี่คืออะไร คำอธิบายเอกสารบอกว่า:

ส่งกลับรูปแบบตัวอักษร String สำหรับ String ที่ระบุ

เมธอดนี้สร้าง String ที่สามารถใช้เพื่อสร้าง Pattern ที่จะจับคู่สตริง s ราวกับว่ามันเป็นรูปแบบตัวอักษร

อักขระเมตาหรือลำดับหลีกในลำดับอินพุตจะไม่มีความหมายพิเศษ

แต่ประเภทการส่งคืนของ Pattern.quote คือ String และไม่ใช่วัตถุ Pattern ที่คอมไพล์แล้ว

เหตุใดจึงต้องใช้วิธีนี้ และตัวอย่างการใช้งานมีอะไรบ้าง


person Prateek    schedule 14.03.2013    source แหล่งที่มา


คำตอบ (6)


\Q หมายถึงจุดเริ่มต้นของข้อความตามตัวอักษร (เช่น เครื่องหมายคำพูดเปิดของ regex)
\E หมายถึงจุดสิ้นสุดของข้อความตามตัวอักษร (เช่น เครื่องหมายคำพูดปิดของ regex)

การเรียกใช้เมธอด Pattern.quote() จะล้อมสตริงด้วย \Q...\E ซึ่งเปลี่ยนข้อความให้เป็น ตัวอักษร regex ตัวอย่างเช่น Pattern.quote(".*") จะจับคู่จุดและเครื่องหมายดอกจัน:

System.out.println("foo".matches(".*")); // true
System.out.println("foo".matches(Pattern.quote(".*"))); // false
System.out.println(".*".matches(Pattern.quote(".*"))); // true

จุดประสงค์ของวิธีนี้คือไม่ต้องการให้โปรแกรมเมอร์ต้องจำคำศัพท์พิเศษ \Q และ \E และเพื่อเพิ่มความสามารถในการอ่านให้กับโค้ดเล็กน้อย - regex นั้นยากพอที่จะอ่านอยู่แล้ว เปรียบเทียบ:

someString.matches(Pattern.quote(someLiteral));
someString.matches("\\Q" + someLiteral + "\\E"));

อ้างถึง จาวาด็อก:

ส่งกลับสตริงรูปแบบตัวอักษรสำหรับสตริงที่ระบุ

เมธอดนี้สร้างสตริงที่สามารถใช้เพื่อสร้างรูปแบบที่จะจับคู่สตริง s ราวกับว่ามันเป็นรูปแบบตัวอักษร

อักขระเมตาหรือลำดับหลีกในลำดับอินพุตจะไม่มีความหมายพิเศษ

person Bohemian♦    schedule 14.03.2013
comment
ค่าที่เทียบเท่ากับ someString.matches(Pattern.quote(someLiteral)) ที่ถูกต้องคือ someString.matches("\\Q" + someLiteral.replace("\\E", "\\E\\\\E\\Q") + "\\E") - person kbolino; 16.05.2016
comment
@kbolino Rofl. แล้วการแทนที่ \\Q ล่ะ? - person Andrew; 23.10.2017
comment
@Andrew มันก็จัดการเรื่องนั้นด้วย: "\\Q\\E".matches(Pattern.quote("\\Q\\E")) // true - person Bohemian♦; 23.10.2017
comment
Nein: \\Q กลายเป็น \\Q\\Q\\E ไม่ใช่เหรอ? - person Andrew; 23.10.2017
comment
@Andrew ใช่ แต่ regex ฉลาดพอที่จะรู้วิธีจัดการกับสิ่งนั้น: ข้อความที่ยกมาคือทุกอย่างตั้งแต่ \Q (พิเศษ) ถึง \E ถัดไป (พิเศษ) ซึ่งอาจรวมถึงลำดับ \Q จำนวนเท่าใดก็ได้ - person Bohemian♦; 23.10.2017

เมธอด Pattern.quote เครื่องหมายคำพูดเป็นส่วนหนึ่งของรูปแบบ regex เพื่อให้ regex ตีความว่าเป็นตัวอักษรสตริง

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

Pattern pattern = Pattern.compile(Pattern.quote(userInput));

วิธีนี้ไม่ใส่เครื่องหมายคำพูด Pattern แต่ตามที่คุณชี้ให้เห็น ให้ล้อม String ไว้ในเครื่องหมายคำพูด regex

person Boris the Spider    schedule 14.03.2013

\Q และ \E รวมถึงสิ่งอื่นๆ ทั้งหมด ได้รับการบันทึกไว้อย่างละเอียดใน java.util .regex.Pattern หน้า Javadoc พวกเขาหมายถึง "เริ่มต้น Quote", "E เครื่องหมายคำพูด" และกำหนดภูมิภาคที่ตัวอักษรทั้งหมดมีความหมายตามตัวอักษร วิธีใช้การส่งคืนของ Pattern.quote คือการป้อนไปที่ Pattern.compile หรือวิธีอื่นใดที่ยอมรับสตริงรูปแบบ เช่น String.split

person Marko Topolnik    schedule 14.03.2013

หากคุณคอมไพล์สตริงที่ส่งคืนโดย Pattern.quote คุณจะได้รับ Pattern ซึ่งตรงกับสตริงตัวอักษรที่คุณ quoted

\Q และ \E ทำเครื่องหมายจุดเริ่มต้นและจุดสิ้นสุดของส่วนที่ยกมาของสตริง

person OpenSauce    schedule 14.03.2013

Regex ขัดแย้งกับสตริงปกติบ่อยครั้ง สมมติว่าฉันต้องการให้ regex ค้นหาสตริงบางตัวที่ทราบเฉพาะตอนรันไทม์เท่านั้น เราจะแน่ใจได้อย่างไรว่าสตริงไม่มีความหมาย regex เช่น(".*.*.*") เราอ้างอิงมัน

person spender    schedule 14.03.2013
comment
ตัวอย่างหนึ่งคือเมื่อคุณต้องการแทนที่สตริงย่อยที่เกิดขึ้นครั้งแรก แต่ String.replaceFirst จะใช้ regex เมื่อคุณต้องการส่งผ่านสตริงตัวอักษร - person Klitos Kyriacou; 13.04.2015

วิธีการนี้ใช้เพื่อสร้างรูปแบบที่ถือเป็นลำดับของอักขระตามตัวอักษร ซึ่งมีผลเหมือนกับธง PATTERN.LITERAL

person logbasex    schedule 02.04.2020