มีสองสิ่งสำคัญที่ควรทราบเกี่ยวกับ[[ ]]
โครงสร้างของ bash ครั้งแรก:
แยก Word และการขยายตัวของพา ธ ที่ยังไม่ได้ดำเนินการเกี่ยวกับคำพูดระหว่าง[[
และ]]
; การขยายตัวทิลเดอพารามิเตอร์และการขยายตัวแปรการขยายเลขคณิตการทดแทนคำสั่งการทดแทนกระบวนการและการลบเครื่องหมายคำพูดจะดำเนินการ
สิ่งที่สอง:
ตัวดำเนินการไบนารีเพิ่มเติม '= ~' พร้อมใช้งาน ... สตริงทางด้านขวาของตัวดำเนินการถือเป็นนิพจน์ทั่วไปแบบขยายและจับคู่ตามนั้น ... ส่วนใดส่วนหนึ่งของรูปแบบอาจถูกยกมาเพื่อบังคับให้จับคู่ เป็นสตริง
ดังนั้น$v
ในด้านใดด้านหนึ่งของ=~
จะถูกขยายเป็นค่าของตัวแปรนั้น แต่ผลลัพธ์จะไม่เป็นการแบ่งคำหรือขยายชื่อพา ธ กล่าวอีกนัยหนึ่งก็คือปลอดภัยอย่างยิ่งที่จะปล่อยให้การขยายตัวแปรโดยไม่ต้องใส่เครื่องหมายอัญประกาศทางด้านซ้ายมือ แต่คุณจำเป็นต้องทราบว่าการขยายตัวแปรจะเกิดขึ้นทางด้านขวามือ
ดังนั้นถ้าคุณเขียน: [[ $x =~ [$0-9a-zA-Z] ]]
ที่$0
ภายใน regex ทางด้านขวาจะขยายก่อน regex จะตีความซึ่งอาจจะทำให้เกิด regex ล้มเหลวในการรวบรวม (ยกเว้นกรณีที่การขยายตัวของ$0
ปลายด้วยตัวเลขหรือเครื่องหมายวรรคตอนสัญลักษณ์ที่มีค่า ASCII น้อยกว่า ตัวเลข) หากคุณอ้างด้านขวามือเช่น[[ $x =~ "[$0-9a-zA-Z]" ]]
นั้นด้านขวามือจะถือว่าเป็นสตริงธรรมดาไม่ใช่นิพจน์ทั่วไป (และ$0
จะยังขยายได้) สิ่งที่คุณต้องการในกรณีนี้คือ[[ $x =~ [\$0-9a-zA-Z] ]]
ในทำนองเดียวกันนิพจน์ระหว่าง[[
และ]]
จะแบ่งออกเป็นคำก่อนที่นิพจน์ทั่วไปจะถูกตีความ ดังนั้นช่องว่างในนิพจน์ทั่วไปจึงต้องมีการหลีกเลี่ยงหรือยกมา [[ $x =~ [0-9a-zA-Z\ ] ]]
หากคุณต้องการที่จะตรงกับตัวอักษรตัวเลขหรือช่องว่างคุณสามารถใช้: อักขระอื่น ๆ ในทำนองเดียวกันจะต้องถูก Escape เช่น#
ซึ่งจะเริ่มแสดงความคิดเห็นหากไม่ได้ยกมา แน่นอนคุณสามารถใส่รูปแบบลงในตัวแปรได้:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
สำหรับ regexes ที่มีอักขระจำนวนมากซึ่งจะต้องมีการ Escape หรือยกมาเพื่อส่งผ่าน bash's lexer หลายคนชอบสไตล์นี้ แต่ระวัง: ในกรณีนี้คุณไม่สามารถอ้างอิงการขยายตัวแปรได้:
if [[ $x =~ "$pat" ]]; then ...
สุดท้ายฉันคิดว่าสิ่งที่คุณพยายามทำคือการตรวจสอบว่าตัวแปรมีเฉพาะอักขระที่ถูกต้องเท่านั้น วิธีที่ง่ายที่สุดในการตรวจสอบนี้คือตรวจสอบให้แน่ใจว่าไม่มีอักขระที่ไม่ถูกต้อง กล่าวอีกนัยหนึ่งการแสดงออกเช่นนี้:
valid='0-9a-zA-Z $%&#'
if [[ ! $x =~ [^$valid] ]]; then ...
!
ลบล้างการทดสอบเปลี่ยนเป็นโอเปอเรเตอร์ "ไม่ตรงกัน" และ[^...]
คลาสอักขระ regex หมายถึง "อักขระใด ๆ ที่ไม่ใช่...
"
การรวมกันของการขยายพารามิเตอร์และตัวดำเนินการ regex สามารถทำให้ไวยากรณ์นิพจน์ทั่วไปของ bash "เกือบอ่านได้" แต่ก็ยังมี gotcha อยู่บ้าง (ไม่ได้มีเสมอไป?) อย่างหนึ่งคือคุณไม่สามารถใส่]
ลงไป$valid
ได้แม้ว่าจะ$valid
มีการยกมายกเว้นในช่วงเริ่มต้น (นั่นเป็นกฎ regex Posix: ถ้าคุณต้องการที่จะรวม]
. ในชั้นเรียนของตัวละครก็ต้องไปที่จุดเริ่มต้น-
สามารถไปที่จุดเริ่มต้นหรือจุดสิ้นสุดดังนั้นหากคุณจำเป็นต้องใช้ทั้ง]
และ-
คุณจะต้องเริ่มต้นด้วย]
และจบลงด้วย-
, นำไปสู่การ regex ว่า "ฉันรู้ว่าสิ่งที่ฉันทำ" อีโมติคอน: [][-]
)