มีสองสิ่งสำคัญที่ควรทราบเกี่ยวกับ[[ ]]โครงสร้างของ 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 ว่า "ฉันรู้ว่าสิ่งที่ฉันทำ" อีโมติคอน: [][-])