ในการแสดงออกปกติตัวละครใดต้องหลบหนี


23

โดยทั่วไปแล้วอักขระใดในนิพจน์ทั่วไปที่ต้องหลบหนี

ตัวอย่างเช่นต่อไปนี้ไม่ถูกต้องทางไวยากรณ์:

echo '[]' | grep '[]'
grep: Unmatched [ or [^

อย่างไรก็ตามสิ่งนี้ถูกต้องตามหลักไวยากรณ์:

echo '[]' | grep '\[]'
[]

มีเอกสารใดบ้างที่ควรหลีกเลี่ยงอักขระในนิพจน์ทั่วไปและไม่ควรใช้?

คำตอบ:


12

ขึ้นอยู่กับแอพพลิเคชั่น ในตัวอย่างของคุณ[จะต้องถูกยกมาเป็นข้อโต้แย้งสำหรับแต่ไม่grepecho

สำหรับเชลล์ (จากข้อกำหนด POSIX ):

การอ้างอิงใช้เพื่อลบความหมายพิเศษของอักขระหรือคำบางคำในเชลล์ การอ้างอิงสามารถใช้เพื่อรักษาความหมายที่แท้จริงของอักขระพิเศษในย่อหน้าถัดไปป้องกันคำที่สงวนไว้ไม่ให้ถูกจดจำเช่นนี้และป้องกันการขยายพารามิเตอร์และการทดแทนคำสั่งภายในการประมวลผลเอกสารที่นี่ (ดูที่นี่เอกสาร)

แอปพลิเคชันจะอ้างอิงตัวอักษรต่อไปนี้หากพวกเขาจะเป็นตัวแทนของตัวเอง:

|  &  ;  <  >  (  )  $  `  \  "  '  <space>  <tab>  <newline>

และต่อไปนี้อาจจำเป็นต้องเสนอราคาภายใต้สถานการณ์บางอย่าง นั่นคือตัวละครเหล่านี้อาจมีความพิเศษขึ้นอยู่กับเงื่อนไขที่อธิบายไว้ในส่วนอื่น ๆ ของไดรฟ์ข้อมูล IEEE Std 1003.1-2001 นี้:

*   ?   [   #   ˜   =   %

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

โปรแกรมเฉพาะ (โดยใช้ regexes, perl, awk) อาจมีข้อกำหนดเพิ่มเติมเกี่ยวกับการหลบหนี


8

แต่ละแอปพลิเคชันจะมีชุดอักขระพิเศษเป็นของตนเอง ปัญหาที่คุณพบคือgrepไม่ใช่เปลือก ต้องระบุอักขระใดgrepอ่านส่วนของ manpage ใน "REGULAR EXPRESSIONS"

สำหรับเชลล์ตัวละครที่ควรจะยกมาคือ:

;'"`#$&*?[]<>{}\

และช่องว่างใด ๆ

ขึ้นอยู่กับเชลล์ตัวละครอื่น ๆ อาจต้องมีการเสนอราคาเช่นกัน:

!^%

ดูใต้ "SHELL GRAMMAR" บน manpage ของเชลล์


ในเชลล์บางตัวที่มีการขยายประวัติ ( bashรวมอยู่ด้วย) !จะยังคงขยายในเครื่องหมายคำพูดคู่เพียงเครื่องหมายคำพูดเดียวเท่านั้นที่จะหยุดการขยายตัว (หรือปิดตัวเลือกเชลล์)
Chris Down

]ไม่ควรเสนอราคา[ไม่เสมอไป ฉันไม่พบการอ้างอิงถึง{และ}
Matteo

8

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

ตัวละครที่มีความพิเศษในบางบริบทเช่น ^พิเศษที่จุดเริ่มต้นของการแสดงออก (ย่อย -) สามารถหนีออกมาได้ในทุกบริบท

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

นิพจน์ปกติพื้นฐาน (BRE)

นิพจน์ปกติเพิ่มเติม (ERE)


3

grepใช้ BRE เป็นวิธีการ regex มีเอกสารที่ดีอยู่ที่นี่บทสรุปทั่วไปจะเป็น "escape อักขระพิเศษหรืออักขระเมตาเพื่อให้ได้ตัวอักษร escape เพื่อสร้าง escape sequences ( \n, \rและอื่น ๆ )" แม้ว่าสิ่งนี้จะไม่จริงเสมอไปตัวอย่างเช่นคุณต้อง หลบหนี(และ)ได้รับความหมายพิเศษของพวกเขา (backreference)


0

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

echo '[]' | grep '[]'

เปลือกส่งอาร์กิวเมนต์[]ไปและจะมีการแยกวิเคราะห์เป็นการแสดงออกวงเล็บไม่ถูกต้องโดยgrepgrep

echo '[]' | grep \[]

ด้านบนเราสามารถเห็นกรณีที่คล้ายกัน เครื่องหมายถูกลบออกและจะถูกส่งเป็นอาร์กิวเมนต์[] รับรู้การแสดงออกวงเล็บที่ไม่ถูกต้องgrepgrep

echo '[]' | grep '\[]'

ในที่สุดในกรณีนี้อัญประกาศจะถูกลบออกโดยเชลล์และ\[]ถูกส่งเป็นอาร์กิวเมนต์ไปgrepแต่ในกรณีเฉพาะนี้¹ \[จะถูกตีความโดยgrepเป็นวงเล็บที่แท้จริง จำเป็นต้องใช้เครื่องหมายคำพูดเพื่อป้องกันการตีความเครื่องหมายทับขวาเป็นอักขระพิเศษของเชลล์


¹ ข้อกำหนด POSIX

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