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
странице ${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
вы можете получить полную мощность PCRE с:
$ 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
Портабельно:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Если в строке есть несколько вхождений шаблона, поведение будет зависеть от всех этих решений. Однако ни один из них не предоставит вам разделенный строкой список всех совпадений, как в вашем решении на grep
основе GNU .
Чтобы сделать это, вам нужно сделать цикл вручную. Например, с 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 и PCRE поддерживают обратные ссылки, но не стандартные ERE, хотя некоторые реализации ERE поддерживают его как расширение. bash
«S [[ foo =~ re ]]
использует Eres.
[[ aa =~ (.)\1 ]]
не будет соответствовать, но
re='(.)\1'; [[ aa =~ $re ]]
может, если ERE системы поддерживают это.