ksh93
dan zsh
memiliki referensi rujukan belakang (atau lebih tepatnya 1 , referensi untuk menangkap kelompok dalam penggantian) di dalam ${var/pattern/replacement}
, tidak 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
halaman manual juga menyebutkan bahwa versi yang akan datang akan mendukungnya ${KSH_MATCH[1]}
untuk grup tangkapan pertama. Belum tersedia pada 2017-04-25).
Namun, dengan bash
, Anda bisa melakukan:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Yang lebih baik karena memeriksa bahwa polanya ditemukan pertama kali.
Jika regexps sistem Anda mendukung \s
/ \S
, Anda juga dapat melakukan:
re='->\s*\S+'
[[ $var =~ $re ]]
Dengan zsh
, Anda bisa mendapatkan kekuatan penuh PCRE dengan:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Dengan zsh -o extendedglob
, lihat juga:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Portabel:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Jika ada beberapa kemunculan pola dalam string, perilaku akan bervariasi dengan semua solusi itu. Namun tidak satu pun dari mereka yang akan memberi Anda daftar yang terpisah dari semua pertandingan seperti di grep
solusi berbasis- GNU Anda .
Untuk melakukan itu, Anda harus melakukan perulangan dengan tangan. Misalnya, dengan bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Dengan zsh
, Anda dapat menggunakan trik semacam ini untuk menyimpan semua pertandingan dalam sebuah array:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 referensi-belakang tidak secara umum menunjuk suatu pola yang merujuk pada apa yang cocok dengan kelompok sebelumnya. Misalnya, \(.\)\1
ekspresi reguler dasar cocok dengan satu karakter diikuti oleh karakter yang sama (cocok aa
, tidak aktif ab
). Itu \1
adalah referensi-kembali ke \(.\)
grup tangkap dalam pola yang sama.
ksh93
memang mendukung back-reference dalam polanya (misalnya ls -d -- @(?)\1
akan mencantumkan nama file yang terdiri dari dua karakter yang identik), bukan shell lain. BRE dan PCRE standar mendukung referensi-belakang tetapi bukan ERE standar, meskipun beberapa implementasi ERE mendukungnya sebagai ekstensi. bash
Ini [[ foo =~ re ]]
menggunakan Eres.
[[ aa =~ (.)\1 ]]
tidak akan cocok, tetapi
re='(.)\1'; [[ aa =~ $re ]]
mungkin jika ERE sistem mendukungnya.