อักขระเมตา Java RegEx (.) และจุดธรรมดา?


150

ใน Java RegEx วิธีการหาความแตกต่างระหว่าง.(dot) อักขระ meta และจุดปกติที่เราใช้ในประโยคใด ๆ วิธีการจัดการกับสถานการณ์ที่ตัวละครเมตาอื่น ๆ มากเกินไปเช่นนี้ ( *, +, \d, ... )

คำตอบ:


276

หากคุณต้องการให้จุดหรือตัวละครอื่น ๆ ที่มีความหมายพิเศษใน regexes เป็นตัวละครปกติคุณจะต้องหลบมันด้วยแบ็กสแลช เนื่องจาก regexes ใน Java เป็นสตริง Java ปกติคุณจึงต้องหลีกเลี่ยงแบ็กสแลชเองดังนั้นคุณต้องมีแบ็กสแลชสองตัวเช่น\\.


1
การแก้ไขนี้ใช้กับ bash ด้วย
krivar

18
โปรดระวังว่าการหลีกเลี่ยงแบ็กสแลชนั้นขึ้นอยู่กับวิธีที่คุณใช้ในการจัดหา regex หากฮาร์ดโค้ดคุณจำเป็นต้องใช้: "\\" หากการอ่านจากแหล่งข้อมูลดิบ (เช่นไฟล์ข้อความ) คุณใช้แบ็กสแลชเดียว: \
Paul

25

การแก้ปัญหาที่เสนอโดยสมาชิกคนอื่นไม่ได้ผลสำหรับฉัน

แต่ฉันพบสิ่งนี้:

เพื่อหนีจุดใน java regexp เขียน [.]


2
เดียวกัน\\.ไม่ได้ทำงานสำหรับฉัน: \.บ่นว่า.ไม่จำเป็นที่จะต้องหนีไป\\.ทำให้มันคิดว่ามันเป็น\.แทน., \\\.และสร้างโยนข้อผิดพลาดที่[.]เป็นสิ่งเดียวที่ทำงาน
mithunc

1
@mithunc มันแปลก\\.ในสตริงตัวอักษรให้คุณ\.ซึ่งเป็นสิ่งที่ regex ต้องการดูจุดเป็นจุดตามตัวอักษรแทนการจับคู่ตัวละครใด ๆ
klaar

16

การแสดงออกปกติสไตล์ Perl (ซึ่งเอ็นจิน Java regex มากหรือน้อยตาม) ถือว่าตัวอักษรต่อไปนี้เป็นตัวอักษรพิเศษ:

.^$|*+?()[{\มีความหมายพิเศษนอกคลาสอักขระ

]^-\มีความหมายพิเศษภายในคลาสอักขระ ( [...])

ดังนั้นคุณต้องหลีกเลี่ยงสัญลักษณ์เหล่านั้น (และเหล่านั้นเท่านั้น) โดยขึ้นอยู่กับบริบท (หรือในกรณีของคลาสอักขระให้วางไว้ในตำแหน่งที่ไม่สามารถตีความผิด)

การหลีกเลี่ยงอักขระอื่นโดยไม่จำเป็นอาจใช้งานได้ แต่เอ็นจิน regex บางตัวจะถือว่านี่เป็นข้อผิดพลาดทางไวยากรณ์ตัวอย่างเช่น\_จะทำให้เกิดข้อผิดพลาดใน. NET

บางคนอื่น ๆ จะนำไปสู่ผลลัพธ์ที่ผิดตัวอย่างเช่น\<ถูกตีความว่าเป็นตัวอักษร<ใน Perl แต่ในegrepนั้นหมายถึง "ขอบเขตของคำ"

ดังนั้นการเขียน-?\d+\.\d+\$เพื่อการแข่งขัน1.50$, -2.00$ฯลฯ และ[(){}[\]]สำหรับตัวละครคลาสที่ตรงกับทุกชนิดของวงเล็บ / วงเล็บ / วงเล็บ

หากคุณต้องการที่จะเปลี่ยนสายป้อนผู้ใช้เป็น regex java.util.regex.Pattern.quoteปลอดภัยรูปแบบการใช้งาน

อ่านเพิ่มเติม: RegexGuru บล็อกของ Jan Goyvaert เกี่ยวกับการหลีกเลี่ยงอักขระ


4

หนีอักขระพิเศษด้วยแบ็กสแลช \., \*, \+, \\dและอื่น ๆ หากคุณไม่แน่ใจคุณสามารถหลีกเลี่ยงอักขระที่ไม่ใช่ตัวอักษรได้ไม่ว่าจะเป็นอักขระพิเศษหรือไม่ก็ตาม ดูที่ javadoc สำหรับ java.util.regex.Patternสำหรับข้อมูลเพิ่มเติม


การหลีกเลี่ยงตัวละครที่ไม่ใช่พิเศษอาจจำเป็นต้องใช้ในบางภาษา แต่อาจล้มเหลวในภาษาอื่นดังนั้นจึงเป็นการดีที่ไม่ให้ติดนิสัย
ทิม Pietzcker

1
คำถามนี้เกี่ยวกับ Java โดยเฉพาะและdocs.oracle.com/javase/6/docs/api/java/util/regex/…กล่าวว่า "อาจใช้แบ็กสแลชก่อนอักขระที่ไม่ใช่ตัวอักษรโดยไม่คำนึงว่าอักขระนั้นเป็น ส่วนหนึ่งของโครงสร้างที่ไม่ใช้ Escape "
Christoffer Hammarström

2

นี่คือรหัสที่คุณสามารถคัดลอกวางได้โดยตรง:

String imageName = "picture1.jpg";
String [] imageNameArray = imageName.split("\\.");
for(int i =0; i< imageNameArray.length ; i++)
{
   system.out.println(imageNameArray[i]);
}

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

String imageName = "picture1  . jpg";
String [] imageNameArray = imageName.split("\\s*.\\s*");
    for(int i =0; i< imageNameArray.length ; i++)
    {
       system.out.println(imageNameArray[i]);
    }

ที่นี่ \\ s * อยู่ที่นั่นเพื่อพิจารณาช่องว่างและให้สตริงที่แยกเท่านั้น


1

ฉันต้องการจับคู่สตริงที่ลงท้ายด้วย ". *" สำหรับสิ่งนี้ฉันต้องใช้สิ่งต่อไปนี้:

"^.*\\.\\*$"

ค่อนข้างโง่ถ้าคุณคิดเกี่ยวกับมัน: D นี่มันหมายความว่าอะไร ที่จุดเริ่มต้นของสตริงสามารถมีอักขระใด ๆ เป็นศูนย์หรือมากกว่าครั้งตามด้วยจุด "." ตามด้วยดาว (*) ที่ท้ายสตริง

ฉันหวังว่านี่จะมีประโยชน์สำหรับใครบางคน ขอบคุณสำหรับแบ็กสแลชของ Fabian


เพียงแค่ใช้"\\.\\*$"แล้ว ไม่จำเป็นต้องตรงกันสำหรับการเริ่มต้นของสตริงถ้ามันไม่สำคัญกับคุณ
Ophidian

ใช่คุณถูกต้อง. ตามความจริงแล้วฉันไม่สามารถจำกรณีการใช้สำหรับสิ่งนี้: /
Atspulgs

ไม่ใช่เพื่อช่วยคุณจริงๆ แต่เพื่อช่วยให้คนอื่นดูโพสต์ของคุณ: P
Ophidian

0

ถ้าคุณต้องการตรวจสอบว่าประโยคของคุณลงท้ายด้วย ". " แล้วคุณต้องเพิ่ม [\. \ ] $ ไปยังจุดสิ้นสุดของรูปแบบของคุณ


0

ฉันกำลังทำอาร์เรย์พื้นฐานบางอย่างใน JGrasp และพบว่าด้วยวิธีการเข้าถึงสำหรับอาร์เรย์ [] [] เพื่อใช้ ('.') เพื่อวางจุดเดียว

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