สตริงโดยหลบหนี Spaces
สตริงสามารถสร้างได้โดยการแทนที่แต่ละช่องว่างด้วยลำดับการเว้นวรรค ' '; เช่นเดียวกับใน:
myVar=การท่องเที่ยวใน Egypt is one of the country 's ชั้นนำ เศรษฐกิจ อุตสาหกรรม
โยนออก $myVar
ผลลัพธ์คือ:
การท่องเที่ยวในอียิปต์เป็นหนึ่งในอุตสาหกรรมเศรษฐกิจชั้นนำของประเทศ
หมายเหตุ: อะพอสทรอฟียังใช้ลำดับการเว้นวรรคด้วย
สตริงโดยคำคมเดียว
โปรแกรมเมอร์มีเวลาที่จะหลบหนีช่องว่างทั้งหมดในสตริงหรือไม่? ไม่ ดังนั้น การใช้อัญประกาศเดี่ยวสองอันเพื่อคั่นสตริงจะดีกว่า เช่น:
myVar='การท่องเที่ยวในอียิปต์เป็นหนึ่งในประเทศ' ''อุตสาหกรรมเศรษฐกิจชั้นนำ.'สตริงที่มีเครื่องหมายอัญประกาศเดี่ยวไม่อนุญาตให้มีการขยาย (แทนที่ด้วยเอฟเฟกต์) ของเอสเคปซีเควนซ์ใดๆ โชคดีที่หากมีการเข้ารหัสสองสตริงติดกัน จะถือเป็นสตริงเดียว สามารถแทรกลำดับการหลบหนีได้ระหว่างดังกล่าว ลำดับการหลบหนีจะขยายออก ดังนั้นผลลัพธ์จะกลายเป็น:
การท่องเที่ยวในอียิปต์เป็นหนึ่งในอุตสาหกรรมเศรษฐกิจชั้นนำของประเทศ
สตริงโดยคำคมคู่
ด้วยเครื่องหมายอัญประกาศคู่ ลำดับหลีกจะไม่ถูกขยายเช่นกัน แต่มีการขยายตัวแปร รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:
myVar=การท่องเที่ยวใน Egypt is one of the country 's ชั้นนำ เศรษฐกิจ อุตสาหกรรมโยนออก $myVar
ผลลัพธ์คือ:
การท่องเที่ยวในอียิปต์เป็นหนึ่งในอุตสาหกรรมเศรษฐกิจชั้นนำของประเทศ
หมายเหตุ: อะพอสทรอฟียังใช้ลำดับการเว้นวรรคด้วย
ในบทความนี้ ประเภทหลักของสตริงที่พิจารณาคือสตริงในเครื่องหมายคำพูดเดี่ยว
พื้นฐานนิพจน์ทั่วไป
Regex
พิจารณาสตริงนี้:
โลกนี้ไม่ใช่บ้านของเราจริงๆ
ให้โลกเป็นสตริงย่อยที่น่าสนใจ จากนั้นสตริงขนาดใหญ่ (ทั้งสตริง) เรียกว่าสตริงเป้าหมายหรือเรียกง่ายๆว่าเป้าหมาย 'โลก' ในเครื่องหมายคำพูดเรียกว่านิพจน์ทั่วไปหรือเรียกง่ายๆว่า regex ในกรณีนี้ เนื้อหา โลก เป็นแบบแผน
จับคู่ง่าย
ในโค้ดต่อไปนี้ หากพบคำว่า 'โลก' ในเป้าหมาย เราจะบอกว่าคำนั้นตรงกัน
NS='โลกนี้ไม่ใช่บ้านของเราจริงๆ'ทะเบียน='โลก'
ถ้า [[ $ str= ~$reg ]];แล้ว
โยนออกพบ
อื่น
โยนออกไม่พบ
เป็น
=~ ซึ่งเป็นตัวดำเนินการกำหนดตามด้วย ~ เรียกว่าตัวดำเนินการผูก เงื่อนไขจะตรวจสอบว่ารูปแบบตรงกับสตริงเป้าหมายหรือไม่ หากพบสตริงย่อยที่สอดคล้องกับรูปแบบในเป้าหมาย คำสั่ง echo จะปรากฏขึ้น หากไม่พบคำสั่ง echo จะไม่พบเสียงสะท้อน ผลลัพธ์สำหรับรหัสนี้คือ:
พบ
ตามแบบฉบับ โลก อยู่ในเป้าหมาย โปรดทราบว่าพื้นที่คั่นหลัง [[ และก่อน ]] ได้รับการคงไว้
ลวดลาย
ในโค้ดด้านบน 'world' ในเครื่องหมายคำพูดคือ regex ในขณะที่ world เป็นรูปแบบ นี่เป็นรูปแบบตรงไปตรงมา อย่างไรก็ตาม รูปแบบส่วนใหญ่ไม่ง่ายอย่างนั้น รูปแบบคือลักษณะของสตริงย่อยที่จะพบ ดังนั้น รูปแบบ Bash จึงใช้อักขระเมตาบางตัว อักขระเมตาคืออักขระเกี่ยวกับอักขระอื่น ตัวอย่างเช่น Bash Pattern ใช้ metacharacters ต่อไปนี้:
^ $ . * +? () [] {} |
นิพจน์ทั่วไปยังสามารถพิมพ์ในวงเล็บคู่เงื่อนไข แต่ไม่จำเป็นต้องอยู่ในเครื่องหมายคำพูด ดังนั้น ในกรณีนี้ มันคือรูปแบบอย่างแท้จริง
คลาสตัวละคร
วงเล็บเหลี่ยม
พบผลลัพธ์ของรหัสต่อไปนี้ หมายความว่ามีการจับคู่เกิดขึ้น:
NS='แมวเข้ามาในห้อง'ถ้า [[ $ str= ~[cbr]ที่]];แล้ว
โยนออกพบ
เป็น
รูปแบบ [cbr]at มีการจับคู่ cat ซึ่งขึ้นต้นด้วย 'c' และดำเนินต่อไปและลงท้ายด้วย at [cbr]at หมายถึง จับคู่ 'c' หรือ 'b' หรือ 'r' ตามด้วย at
พบผลลัพธ์ของรหัสต่อไปนี้ หมายความว่ามีการจับคู่เกิดขึ้น:
NS='ค้างคาวเข้ามาในห้อง'ถ้า [[ $ str= ~[cbr]ที่]];แล้ว
โยนออกพบ
เป็น
รูปแบบ [cbr]at ตรงกับ bat ซึ่งขึ้นต้นด้วย 'b' และดำเนินต่อไปและลงท้ายด้วย at [cbr]at หมายถึง จับคู่ 'c' หรือ 'b' หรือ 'r' ตามด้วย at
พบผลลัพธ์ของรหัสต่อไปนี้ หมายความว่ามีการจับคู่เกิดขึ้น:
NS='หนูเข้ามาในห้อง'ถ้า [[ $ str= ~[cbr]ที่]];แล้ว
โยนออกพบ
เป็น
รูปแบบ [cbr]at ตรงกับ rat ซึ่งขึ้นต้นด้วย 'r' และต่อด้วย at
ในตัวอย่างโค้ดข้างต้น โปรแกรมเมอร์ไม่ทราบว่า cat หรือ bat หรือ rat มีอยู่ในสตริงเป้าหมายหรือไม่ แต่เขารู้ว่าสตริงย่อยเริ่มต้นด้วย 'c' หรือ 'b' หรือ 'r' จากนั้นดำเนินการต่อและลงท้ายด้วย at วงเล็บเหลี่ยมในรูปแบบช่วยให้อักขระต่างๆ ที่เป็นไปได้สามารถจับคู่อักขระหนึ่งตัวในตำแหน่งที่สัมพันธ์กับอักขระอื่นๆ ในเป้าหมายได้ ดังนั้น วงเล็บเหลี่ยมมีชุดอักขระ ซึ่งตรงกับชุดอักขระย่อย ในที่สุดก็เป็นสตริงย่อยที่สมบูรณ์ที่ตรงกัน
ช่วงของตัวละคร
ในรหัสด้านบน [cbr] เป็นคลาส แม้ว่า 'c' หรือ 'b' หรือ 'r' จะสอดคล้องกับอักขระตัวเดียว หากตามหลังไม่ตรงกัน รูปแบบจะไม่ตรงกับสิ่งใด
มีบางช่วงที่จะสร้างคลาส ตัวอย่างเช่น 0 ถึง 9 หลักในรูปแบบคลาส [0-9] โดยรวม 0 และ 9 ตัวพิมพ์เล็ก 'a' ถึง 'z' สร้างคลาส [a-z] โดยรวม 'a' และ 'z' ตัวพิมพ์ใหญ่ 'A' ถึง 'Z' สร้างคลาส [A-Z] โดยรวม 'A' และ 'Z' จากคลาส เป็นอักขระตัวหนึ่งที่จะจับคู่อักขระหนึ่งตัวในสตริง
รหัสต่อไปนี้สร้างการจับคู่:
ถ้า [[ 'ID8id'= ~[0-9] ]];แล้วโยนออกพบ
เป็น
คราวนี้เป้าหมายเป็นสตริงตามตัวอักษรในเงื่อนไข 8 ซึ่งเป็นหนึ่งในตัวเลขที่เป็นไปได้ภายในช่วง [0-9] ตรงกับ 8 ในสตริง 'ID8id' รหัสข้างต้นเทียบเท่ากับ:
ถ้า [[ 'ID8id'= ~[0123456789] ]];แล้วโยนออกพบ
เป็น
ในที่นี้ ตัวเลขที่เป็นไปได้ทั้งหมดถูกเขียนในรูปแบบ ดังนั้นจึงไม่มียัติภังค์
ในรหัสต่อไปนี้จะได้รับการจับคู่:
ถ้า [[ 'ID8iD'= ~[a-z] ]];แล้วโยนออกพบ
เป็น
การจับคู่อยู่ระหว่าง 'i' ตัวพิมพ์เล็กของช่วง [a-z] และตัวพิมพ์เล็ก 'i' ของสตริงเป้าหมาย 'ID8iD'
จำไว้ว่าช่วงนั้นเป็นคลาส ชั้นเรียนสามารถเป็นส่วนหนึ่งของรูปแบบที่ใหญ่กว่าได้ ดังนั้นในรูปแบบ ข้อความสามารถอยู่ด้านหน้าและ/หรือหลังชั้นเรียน รหัสต่อไปนี้แสดงให้เห็นสิ่งนี้:
ถ้า [[ 'ID8id เป็นตัวระบุ'=~ ID[0-9]NS ]];แล้วโยนออกพบ
เป็น
ผลลัพธ์คือ: พบ 'ID8id' จากรูปแบบตรงกับ 'ID8id' ในสตริงเป้าหมาย
การปฏิเสธ
การจับคู่ไม่ได้มาจากรหัสต่อไปนี้:
ถ้า [[ '0123456789101112'= ~[^0-9] ]];แล้วโยนออกพบ
อื่น
โยนออกไม่พบ
เป็น
ผลลัพธ์คือ:
ไม่พบ
ถ้าไม่มี ^ ข้างหน้าช่วง ภายในวงเล็บเหลี่ยม ศูนย์ของช่วงจะตรงกับศูนย์แรกของสตริงเป้าหมาย ดังนั้น ^ ที่ด้านหน้าของช่วง (หรืออักขระเสริม) จะลบล้างคลาส
รหัสต่อไปนี้สร้างการจับคู่เนื่องจากเงื่อนไขอ่าน: จับคู่อักขระที่ไม่ใช่ตัวเลขที่ใดก็ได้ในเป้าหมาย:
ถ้า [[ 'ABCDEFGHIJ'= ~[^0-9] ]];แล้วโยนออกพบ
อื่น
โยนออกไม่พบ
เป็น
ดังนั้นผลลัพธ์คือ: found
[^0-9] หมายถึงไม่ใช่ตัวเลข ดังนั้น [^0-9] จึงเป็นค่าลบของ [0-9]
[^a-z] หมายถึงตัวอักษรที่ไม่ใช่ตัวพิมพ์เล็ก ดังนั้น [^a-z] จึงเป็นค่าลบของ [a-z]
[^A-Z] หมายถึงตัวอักษรที่ไม่ใช่ตัวพิมพ์ใหญ่ ดังนั้น [^A-Z] จึงเป็นค่าลบของ [A-Z]
มีการปฏิเสธอื่น ๆ
ช่วงเวลา (.) ในรูปแบบ
จุด (.) ในรูปแบบตรงกับอักขระใดๆ รวมทั้งตัวมันเอง พิจารณารหัสต่อไปนี้:
ถ้า [[ '6759WXY.A3'= ~ 7.9W.Y.A]];แล้วโยนออกพบ
เป็น
พบผลลัพธ์ของรหัสเนื่องจากอักขระอื่นตรงกัน หนึ่งจุดตรงกับ '5'; จุดอื่นตรงกับ 'X'; และจุดสุดท้ายตรงกับจุด
การจับคู่สลับ
พิจารณาประโยคนี้สำหรับสตริงเป้าหมาย:
กรงมีนกหลายชนิด
บางคนอาจต้องการทราบว่าเป้าหมายนี้มีนกพิราบหรือนกยูงหรือนกอินทรีหรือไม่ สามารถใช้รหัสต่อไปนี้:
NS='กรงมีนกยูงหลายชนิด'ถ้า [[ $ str=~ นกพิราบ|นกยูง|อินทรี]];แล้ว
โยนออกพบ
อื่น
โยนออกไม่พบ
เป็น
ผลลัพธ์คือพบ การเปลี่ยน metacharacter | ได้รับการว่าจ้าง อาจมีทางเลือกสอง สาม สี่ และอื่นๆ สิ่งที่ตรงกันในรหัสนี้คือ 'นกยูง'
การจัดกลุ่ม
ในรูปแบบต่อไปนี้ วงเล็บถูกใช้เพื่อจัดกลุ่มอักขระ:
เวที (นักเต้น)
กลุ่มนี้เป็นนักเต้นบนเวทีที่ล้อมรอบด้วยเมตาคาแรคเตอร์ ( และ ) (นักเต้น) เป็นกลุ่มย่อยในขณะที่เวที (นักเต้น) คือทั้งกลุ่ม พิจารณาสิ่งต่อไปนี้:
(นักเต้นยอดเยี่ยมมาก)
ที่นี่กลุ่มย่อยหรือสตริงย่อยคือนักเต้นที่ยอดเยี่ยม
สตริงย่อยที่มีส่วนร่วม
ผู้มีส่วนได้ส่วนเสียคือบุคคลที่มีความสนใจในธุรกิจ ลองนึกภาพธุรกิจที่มีเว็บไซต์ stake.com ลองนึกภาพว่าหนึ่งในสตริงเป้าหมายต่อไปนี้อยู่ในคอมพิวเตอร์:
เว็บไซต์ Stake.com มีไว้สำหรับธุรกิจ
มีผู้มีส่วนได้ส่วนเสีย.;
ผู้มีส่วนได้ส่วนเสียทำงานให้กับ stake.com.;
ให้สตริงใด ๆ เหล่านี้เป็นเป้าหมาย โปรแกรมเมอร์อาจต้องการทราบว่า stake.com หรือผู้มีส่วนได้ส่วนเสียอยู่ในสตริงเป้าหมายหรือไม่ รูปแบบของเขาจะเป็น:
Stake.com|ผู้มีส่วนได้ส่วนเสีย
โดยใช้การสลับ
เดิมพันถูกพิมพ์สองครั้งในสองคำ สามารถหลีกเลี่ยงได้โดยการพิมพ์รูปแบบดังนี้:
เดิมพัน(.com|ผู้ถือ)
.com|holder คือกลุ่มย่อยในกรณีนี้
หมายเหตุ: การใช้อักขระสลับในกรณีนี้ Stake.com หรือผู้มีส่วนได้ส่วนเสียจะยังคงถูกค้นหา พบผลลัพธ์ของรหัสต่อไปนี้:
NS='เว็บไซต์ stake.com มีไว้เพื่อธุรกิจ'ถ้า [[ $ str=~ เดิมพัน(.กับ|ที่ยึด) ]];แล้ว
โยนออกพบ
เป็น
สตริงย่อยที่ตรงกันคือ Stake.com
อาร์เรย์ที่กำหนดไว้ล่วงหน้า BASH_REMATCH
BASH_REMATCH เป็นอาร์เรย์ที่กำหนดไว้ล่วงหน้า สมมติว่ารูปแบบมีกลุ่ม ทั้งกลุ่มที่ตรงกัน จะเข้าสู่เซลล์เพื่อหาดัชนี 0 ของอาร์เรย์นี้ กลุ่มย่อยแรกที่ตรงกันจะเข้าสู่เซลล์สำหรับดัชนี 1; กลุ่มย่อยที่สองตรงกัน เข้าไปในเซลล์สำหรับดัชนี 2 และอื่นๆ รหัสต่อไปนี้แสดงวิธีใช้อาร์เรย์นี้:
NS='นักเต้นบนเวทีมาแล้ว'ถ้า [[ $ str=~ เวที(นักเต้น) ]];แล้ว
โยนออกพบ
เป็น
สำหรับผมใน ${!BASH_REMATCH[@]};ทำ
printf '${BASH_REMATCH[i]}, '
เสร็จแล้ว
โยนออก
ผลลัพธ์คือ:
พบ
นักเต้นบนเวที, นักเต้น,
ทั้งกลุ่มเป็นนักเต้นบนเวที มีกลุ่มย่อยเพียงกลุ่มเดียวคือนักเต้น
หมายเหตุ: เว้นวรรคในลวดลายแล้ว
การจับคู่ความเป็นอิสระของตัวพิมพ์ใหญ่ / ล่าง
การจับคู่ตามที่อธิบายข้างต้นจะคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ การจับคู่สามารถทำได้โดยไม่ขึ้นอยู่กับกรณี นี่คือภาพประกอบในรหัสต่อไปนี้:
ร้านค้า -NSnocasematchNS='เราชอบเพลงดีๆ'
ถ้า [[ $ str=~ ดี]];แล้ว
โยนออกพบ
เป็น
ร้านค้า -ยูnocasematch
ผลลัพธ์คือ: พบ รูปแบบคือ GoodOd สตริงย่อยที่ตรงกันคือ 'ดี' โปรดทราบว่ามีการเปิดใช้ตัวเลือก nocasematch ที่จุดเริ่มต้นของส่วนโค้ดและปิดใช้งานเมื่อสิ้นสุดส่วนของโค้ด
ความยาวของสตริง
ไวยากรณ์ที่จะได้รับความยาวของสตริงคือ:
${#PARAMETER}ตัวอย่าง:
NS='เราชอบเพลงดีๆ'โยนออก $ {# str}
ผลลัพธ์คือ: 19
ลดสตริง
ไวยากรณ์สำหรับการลดสตริงคือ:
${พารามิเตอร์:ออฟเซ็ต}${PARAMETER:OFFSET:LENGTH}
โดยที่การนับ OFFSET เริ่มจากศูนย์
ตัวอย่างต่อไปนี้แสดงวิธีการลบอักขระ 11 ตัวแรกของสตริง:
NS='ฉันมักจะเต้นไปกับเพลงที่ดี'โยนออก $ {str: 10}
ผลลัพธ์คือ:
เพลงที่ดี
นับ LENGTH เริ่มจากตัวถัดไป รหัสต่อไปนี้แสดงวิธีที่อนุญาตให้ใช้ส่วนภายในสตริง:
NS='ฉันมักจะเต้นไปกับเพลงที่ดี'โยนออก $ {str: 10: 6}
ผลลัพธ์คือ:
ance t
อักขระ 11 ตัวแรกถูกลบ; อนุญาตให้ใช้อักขระ 6 ตัวถัดไป และอักขระที่เหลือจะถูกลบออกโดยอัตโนมัติ
ค้นหาและแทนที่
เมื่อพบสตริงย่อย จะสามารถแทนที่ด้วยสตริงย่อยอื่นได้ ไวยากรณ์สำหรับสิ่งนี้คือ:
ที่ไหน=${พารามิเตอร์/รูปแบบ/การเปลี่ยน}ที่ไหน=${พารามิเตอร์//PATTERN/REPLACEMENT}
ที่ไหน=${พารามิเตอร์/รูปแบบ}
ที่ไหน=${พารามิเตอร์//รูปแบบ}
สำหรับไวยากรณ์แรกที่มีเครื่องหมายทับเดี่ยว เฉพาะการจับคู่ครั้งแรกเท่านั้นที่จะถูกแทนที่ ตัวอย่าง:
NS='มีหนู ค้างคาว และแมว อยู่ในห้อง'ขวา=${str/[cbr]at/วัวใหญ่}
โยนออก $ str
โยนออก $ ret
ผลลัพธ์คือ:
มีหนู ค้างคาว และแมว อยู่ในห้อง
มีวัวตัวใหญ่ ค้างคาว และแมว อยู่ในห้อง
สำหรับไวยากรณ์ที่สองที่มีเครื่องหมายทับคู่ การแข่งขันทั้งหมดจะถูกแทนที่ ตัวอย่าง:
NS='มีหนู ค้างคาว และแมว อยู่ในห้อง'ขวา=${str//[cbr]at/big cow}
โยนออก $ str
โยนออก $ ret
ผลลัพธ์คือ:
มีหนู ค้างคาว และแมว อยู่ในห้อง
มีวัวตัวใหญ่ วัวตัวใหญ่ และวัวตัวใหญ่อยู่ในห้อง
สำหรับไวยากรณ์ที่สามที่มีเครื่องหมายทับเดี่ยว จะไม่มีการแทนที่สำหรับการจับคู่ครั้งแรกและครั้งเดียว
นอกจากนี้ สตริงย่อยแรกที่พบจะถูกลบออก ตัวอย่าง:
NS='มีหนู ค้างคาว และแมว อยู่ในห้อง'ขวา=${str/[cbr]ที่}
โยนออก $ str
โยนออก $ ret
สำหรับไวยากรณ์ที่สี่ที่มีเครื่องหมายทับคู่ จะไม่มีการแทนที่สำหรับการแข่งขันทั้งหมด นอกจากนี้ สตริงย่อยทั้งหมดที่พบจะถูกลบออก ตัวอย่าง:
NS='มีหนู ค้างคาว และแมว อยู่ในห้อง'ขวา=${str//[cbr]ที่}
โยนออก $ str
โยนออก $ ret
ผลลัพธ์คือ:
มีหนู ค้างคาว และแมว อยู่ในห้อง
มี a , a และ a , ในห้องเพาะเลี้ยง
บทสรุป
ในการตรวจสอบว่าสตริงมีสตริงย่อยใน Bash หรือไม่ ต้องใช้การจับคู่รูปแบบ การจับคู่รูปแบบไม่ได้เกิดขึ้นเฉพาะในวงเล็บคู่เงื่อนไข [[ . . . ]]. นอกจากนี้ยังสามารถเกิดขึ้นได้ในการขยายพารามิเตอร์ด้วย ${ . .}. ด้วยการขยายพารามิเตอร์ สามารถรับสตริงย่อยตามดัชนีได้
สิ่งที่นำเสนอในบทความนี้คือประเด็นที่สำคัญที่สุดในการจับคู่รูปแบบ มีมากขึ้น! อย่างไรก็ตาม สิ่งที่ผู้อ่านควรศึกษาต่อไปคือการขยายชื่อไฟล์