ksh93
ve içeride zsh
geri referans (veya daha doğrusu 1 , yedek gruptaki yakalama gruplarına referanslar) desteği var ${var/pattern/replacement}
, değil 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 sayfasında ayrıca gelecekteki sürümlerin ${KSH_MATCH[1]}
ilk yakalama grubu için destekleneceği belirtiliyor. 2017-04-25 itibariyle henüz mevcut değil).
Ancak, bash
şunları yapabilirsiniz:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Bu daha önce desenin bulunup bulunmadığını kontrol ettiği için daha iyidir.
Sisteminizin normal ifadeleri \s
/ varsa \S
, şunları da yapabilirsiniz:
re='->\s*\S+'
[[ $var =~ $re ]]
İle zsh
, PCRE'lerin tüm gücünü aşağıdakilerle elde edebilirsiniz:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
İle zsh -o extendedglob
, ayrıca bkz:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
portably:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Dizede desenin birkaç kez tekrarlanması durumunda, davranış tüm bu çözümlere göre değişir. Ancak bunların hiçbiri size GNU grep
tabanlı çözümünüzdeki gibi tüm karşılaşmaların satır satırından ayrı bir listesini vermeyecektir .
Bunu yapmak için, döngüyü elle yapmanız gerekir. Örneğin bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
İle zsh
, bir dizideki tüm maçları saklamak için bu tür bir numaraya başvurabilirsiniz:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 geri referanslar, daha önceki bir grup tarafından eşleşenlere referans veren bir paterni daha yaygın olarak tanımlar. Örneğin, \(.\)\1
temel normal ifade tek bir karakterle ve ardından aynı karakterle (açık aa
değil, eşleşir ab
) eşleşir . Bu \1
, \(.\)
aynı kalıptaki yakalama grubuna bir geri başvurudır .
ksh93
kalıplarında geri başvuruları desteklemez (örneğin ls -d -- @(?)\1
, iki kabuktan oluşan dosya adlarını listeler), diğer kabukları değil. Standart BRE'ler ve PCRE'ler geri referansları destekler, ancak standart ERE'yi desteklemez, ancak bazı ERE uygulamaları bunu bir uzantı olarak destekler. bash
's [[ foo =~ re ]]
kullanımları EREŞ.
[[ aa =~ (.)\1 ]]
eşleşmeyecek, ama
re='(.)\1'; [[ aa =~ $re ]]
sistemin ERE'leri destekliyorsa olabilir.