ksh93
และzsh
มีการกลับอ้างอิง (หรือมากกว่าถูกต้อง1การอ้างอิงไปยังกลุ่มการจับภาพในการทดแทน) การสนับสนุนภายในไม่${var/pattern/replacement}
bash
ksh93
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ printf '%s\n' "${var/*@(->*([[:space:]])+([^[:space:]]))*/\1}"
-> r1-ae0-2
zsh
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ set -o extendedglob
$ printf '%s\n' "${var/(#b)*(->[[:space:]]#[^[:space:]]##)*/$match[1]}"
-> r1-ae0-2
( mksh
man page ระบุด้วยว่าเวอร์ชันในอนาคตจะรองรับกับ${KSH_MATCH[1]}
กลุ่มการจับภาพครั้งแรกยังไม่พร้อมให้บริการตั้งแต่วันที่ 2017-04-25)
อย่างไรก็ตามด้วยbash
คุณสามารถทำสิ่งต่อไปนี้
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
ซึ่งจะดีกว่าเพราะจะตรวจสอบว่าพบลวดลายก่อนหรือไม่
หากระบบของคุณรองรับ\s
/ \S
คุณสามารถทำสิ่งต่อไปนี้
re='->\s*\S+'
[[ $var =~ $re ]]
ด้วยzsh
, คุณสามารถใช้ PCREs ได้อย่างเต็มประสิทธิภาพด้วย:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
ด้วยzsh -o extendedglob
ดู:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
portably:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
หากมีหลายรูปแบบในสตริงพฤติกรรมจะแตกต่างกันไปตามวิธีแก้ปัญหาทั้งหมด อย่างไรก็ตามจะไม่มีรายการใดรายการหนึ่งให้คุณคั่นรายการขึ้นบรรทัดใหม่ของรายการที่ตรงกันทั้งหมดใน GNU ของคุณgrep
แก้ปัญหาชั่น
ในการทำเช่นนั้นคุณจะต้องวนซ้ำด้วยมือ ตัวอย่างเช่นด้วยbash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
ด้วยzsh
, คุณสามารถใช้กลอุบายประเภทนี้เพื่อเก็บการแข่งขันทั้งหมดในอาเรย์:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1การอ้างอิงย้อนกลับมักจะกำหนดรูปแบบที่อ้างอิงสิ่งที่ถูกจับคู่โดยกลุ่มก่อนหน้า ตัวอย่างเช่น\(.\)\1
นิพจน์ทั่วไปพื้นฐานจับคู่อักขระเดียวตามด้วยอักขระเดียวกันนั้น (ตรงกับaa
ไม่ใช่บนab
) นั่น\1
คือการอ้างอิงย้อนกลับไปยัง\(.\)
กลุ่มการจับภาพนั้นในรูปแบบเดียวกัน
ksh93
สนับสนุนการอ้างอิงกลับในรูปแบบ (ตัวอย่างเช่นls -d -- @(?)\1
จะแสดงรายการชื่อไฟล์ที่ประกอบด้วยอักขระสองตัวที่เหมือนกัน) ไม่ใช่เชลล์อื่น ๆ BRE มาตรฐานและ PCREs สนับสนุนการอ้างอิงย้อนกลับ แต่ไม่ใช่ ERE มาตรฐานแม้ว่าการปรับใช้ ERE บางอย่างรองรับเป็นส่วนขยาย bash
's [[ foo =~ re ]]
ใช้ Eres
[[ aa =~ (.)\1 ]]
จะไม่ตรงกัน แต่
re='(.)\1'; [[ aa =~ $re ]]
อาจถ้า ERE ของระบบสนับสนุน