ksh93
i zsh
mieć w sobie odniesienia (lub dokładniej 1 , odniesienia do grup przechwytywania w zastępstwie) ${var/pattern/replacement}
, nie 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
strona ${KSH_MATCH[1]}
podręcznika wspomina również, że przyszłe wersje będą go obsługiwać dla pierwszej grupy przechwytywania. Jeszcze niedostępne od 25.04.2017).
Jednak za pomocą bash
możesz:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Co jest lepsze, ponieważ sprawdza, czy wzorzec zostanie znaleziony jako pierwszy.
Jeśli obsługa wyrażeń regularnych w twoim systemie \s
/ \S
, możesz także:
re='->\s*\S+'
[[ $var =~ $re ]]
Dzięki zsh
możesz uzyskać pełną moc PCRE dzięki:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Z zsh -o extendedglob
zobacz także:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Przenośny:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Jeśli w ciągu występuje kilka wystąpień wzorca, zachowanie będzie się różnić dla wszystkich tych rozwiązań. Jednak żadna z nich nie da ci oddzielnej listy wszystkich dopasowań, jak w twoim grep
rozwiązaniu opartym na GNU.
Aby to zrobić, musisz ręcznie wykonać pętlę. Na przykład z bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Dzięki zsh
możesz skorzystać z tego rodzaju sztuczki, aby zapisać wszystkie dopasowania w tablicy:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 odniesienia wsteczne częściej oznaczają wzorzec, który odwołuje się do tego, co pasowało do wcześniejszej grupy. Na przykład \(.\)\1
podstawowe wyrażenie regularne dopasowuje pojedynczy znak, po którym następuje ten sam znak (pasuje on aa
, a nie on ab
). Jest \1
to odniesienie do tej \(.\)
grupy przechwytywania według tego samego wzorca.
ksh93
obsługuje wzorce wsteczne (na przykład ls -d -- @(?)\1
wyświetla nazwy plików składające się z dwóch identycznych znaków), a nie inne powłoki. Standardowe BRE i PCRE obsługują referencje wsteczne, ale nie standardowe ERE, chociaż niektóre implementacje ERE obsługują je jako rozszerzenie. bash
„S [[ foo =~ re ]]
Używa ERES.
[[ aa =~ (.)\1 ]]
nie będzie pasować, ale
re='(.)\1'; [[ aa =~ $re ]]
może, jeśli ERE systemu to obsługuje.