ไม่สามารถหนีแบ็กสแลชด้วย regex ได้หรือไม่?


114

ฉันใช้ regex ต่อไปนี้

^[a-zA-Z0-9\',!;\?\$\^:\\\/`\|~&\" @#%\*\{}\(\)_\+\.\s=-]{1,1000}$

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


4
ฉันเพิ่งแก้ไขการพิมพ์ผิดในชื่อ แต่มีบางอย่างที่ยอดเยี่ยมมากเกี่ยวกับชื่อเรื่อง "ไม่สามารถหลีกหนีฟันเฟืองด้วยนิพจน์ทั่วไปได้หรือไม่" แน่นอน!
Adam Crossland

1
@AdamCrossland เราทุกคนไม่หวังว่า regex จะช่วยให้เรารอดพ้นจากฟันเฟืองได้หรือ? > _>
Eton B.

2
ห่าฉันแค่หวังว่าฉันจะรอดพ้นจากฟันเฟืองจาก regex
Adam Crossland

คำตอบ:


227

หากคุณใส่สิ่งนี้ไว้ในสตริงภายในโปรแกรมคุณอาจต้องใช้แบ็กสแลชสี่ตัว (เนื่องจากตัวแยกวิเคราะห์สตริงจะลบสองตัวออกเมื่อ "ยกเลิกการหลบหนี" สำหรับสตริงจากนั้น regex ต้องการสองตัวสำหรับ แบ็กสแลช regex ที่หลบหนี)

ตัวอย่างเช่น:

regex("\\\\")

ถูกตีความว่า ...

regex("\\" [escaped backslash] followed by "\\" [escaped backslash])

ถูกตีความว่า ...

regex(\\)

ถูกตีความว่าเป็นนิพจน์ทั่วไปที่ตรงกับแบ็กสแลชเดียว


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

re.compile(r'\\')

rในด้านหน้าของคำพูดที่ทำให้มันดิบสตริงซึ่งไม่ได้หนีทับขวาแยก


14
ฮิฮิ ... ฉันเพิ่งเจอสิ่งนี้และต้องการเพิ่มสาม ฉันแค่เพิ่มแบ็กสแลชไปเรื่อย ๆ จนกว่าจะได้ผล
billynoah

อืมทำไม regex บนโลกนี้ถึงตีความซ้ำสองครั้งแทนที่จะเป็นครั้งเดียวเหมือนที่ควรจะเป็นสำหรับ PCRE?
Jim Michaels

3
@JimMichaels เนื่องจากไม่ใช่ทุกภาษาที่มีตัวอักษร regex ที่ไม่ใช้ Escape และในบางครั้งภาษาโปรแกรมเองก็ตีความว่า slash Escape หนึ่งครั้งในรูปแบบสตริงของมันจากนั้นสตริงผลลัพธ์จะถูกส่งไปยัง regex engine (ซึ่งตีความ slash escape ในไวยากรณ์ regex)
Amber

1
ครั้งหนึ่งเมื่อนานมาแล้วฉันต้องจับ xpath ขององค์ประกอบที่มีคุณสมบัติการระบุเพียงอย่างเดียวคือพา ธ ไฟล์ windows จากนั้นสร้างโปรแกรม (เป็นสตริง) ซึ่ง xpath จะแสดงเป็นสตริง เมื่อถึงจุดหนึ่งในขั้นตอนกลางจะมี 8 แบ็กสแลชที่ใช้เพื่อแสดงแบ็กสแลชเดียวในเส้นทางไฟล์ นั่นเป็นสิ่งที่สูงที่สุดที่ฉันเคยได้มา
Zackkenyon

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

15

หากไม่ใช่ตัวอักษรคุณต้องใช้\\\\เพื่อให้ได้\\ซึ่งหมายถึงแบ็กสแลชที่ใช้ Escape

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


10

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

\ (backslash) followed by any of [\^$.|?*+(){} escapes the special character to suppress its special meaning.

อ้างอิง: http://www.regular-expressions.info/reference.html


4

จากhttp://www.regular-expressions.info/charclass.html :

โปรดสังเกตว่าอักขระพิเศษหรืออักขระเมตาภายในคลาสอักขระเท่านั้นคือวงเล็บปิด (]), แบ็กสแลช (\\), เครื่องหมายคาเร็ต (^) และยัติภังค์ (-) อักขระเมตาตามปกติเป็นอักขระปกติภายในคลาสอักขระและไม่จำเป็นต้องหลีกเลี่ยงด้วยแบ็กสแลช หากต้องการค้นหาดาวหรือเครื่องหมายบวกให้ใช้ [+ *] regex ของคุณจะทำงานได้ดีหากคุณหลีกเลี่ยงอักขระเมตาปกติภายในคลาสอักขระ แต่การทำเช่นนั้นจะลดความสามารถในการอ่านลงอย่างมาก

หากต้องการรวมแบ็กสแลชเป็นอักขระที่ไม่มีความหมายพิเศษใด ๆ ในคลาสอักขระคุณต้องหลีกเลี่ยงด้วยแบ็กสแลชอื่น [\\ x] จับคู่แบ็กสแลชหรือ x สามารถรวมวงเล็บปิด (]), คาเร็ต (^) และยัติภังค์ (-) ได้โดยใช้แบ็กสแลชหรือโดยการวางไว้ในตำแหน่งที่ไม่ใช้ความหมายพิเศษ ฉันแนะนำวิธีหลังเนื่องจากช่วยเพิ่มความสามารถในการอ่าน ในการใส่คาเร็ตให้วางไว้ที่ใดก็ได้ยกเว้นด้านหลังวงเล็บเปิด [x ^] จับคู่ x หรือเครื่องหมายคาเร็ต คุณสามารถใส่วงเล็บปิดได้ทันทีหลังวงเล็บเปิดหรือคาเร็ตลบ [] x] จับคู่วงเล็บปิดหรือ x [^] x] จับคู่อักขระใด ๆ ที่ไม่ใช่วงเล็บปิดหรือ x สามารถใส่ยัติภังค์ไว้หลังวงเล็บเปิดหรือก่อนวงเล็บปิดหรืออยู่หลังเครื่องหมายคาเร็ตลบได้

คุณเขียนนิพจน์ทั่วไปในภาษาอะไร


0

วิธีนี้แก้ไขปัญหาของฉันในขณะที่เปลี่ยน br tag เป็น '\ n'

alert(content.replace(/<br\/\>/g,'\n'));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.