ksh93
et zsh
ont un support de référence arrière (ou plus précisément 1 , des références aux groupes de capture dans le remplacement) à l'intérieur ${var/pattern/replacement}
, non 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
(la mksh
page de manuel mentionne également que les futures versions le prendront en charge ${KSH_MATCH[1]}
pour le premier groupe de capture. Pas encore disponible à partir du 25/04/2017).
Cependant, avec bash
, vous pouvez faire:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Ce qui est mieux car il vérifie que le motif est trouvé en premier.
Si les regexps de votre système prennent en charge \s
/ \S
, vous pouvez également faire:
re='->\s*\S+'
[[ $var =~ $re ]]
Avec zsh
, vous pouvez obtenir toute la puissance des PCRE avec:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Avec zsh -o extendedglob
, voir aussi:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Portablement:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
S'il existe plusieurs occurrences du modèle dans la chaîne, le comportement variera avec toutes ces solutions. Cependant, aucun d'eux ne vous donnera une liste séparée par des sauts de ligne de toutes les correspondances comme dans votre grep
solution basée sur GNU .
Pour ce faire, vous devez effectuer le bouclage à la main. Par exemple, avec bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Avec zsh
, vous pouvez recourir à ce genre d'astuce pour stocker toutes les correspondances dans un tableau:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 Les références arrières désignent plus communément un modèle qui fait référence à ce qui correspondait à un groupe précédent. Par exemple, l' \(.\)\1
expression régulière de base correspond à un seul caractère suivi de ce même caractère (il correspond à aa
, pas à ab
). C'est \1
une référence arrière à ce \(.\)
groupe de capture dans le même modèle.
ksh93
prend en charge les références arrières dans ses modèles (par exemple ls -d -- @(?)\1
listera les noms de fichiers qui se composent de deux caractères identiques), pas d'autres shells. Les BRE et PCRE standard prennent en charge les références arrières mais pas les ERE standard, bien que certaines implémentations ERE le prennent en charge en tant qu'extension. bash
« s [[ foo =~ re ]]
utilisations ERE.
[[ aa =~ (.)\1 ]]
ne correspondra pas, mais
re='(.)\1'; [[ aa =~ $re ]]
peut si les ERE du système le prennent en charge.