ksh93
và zsh
có tham chiếu ngược (hoặc chính xác hơn là 1 , tham chiếu đến các nhóm bắt trong thay thế) ${var/pattern/replacement}
, không hỗ trợ 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
trang man cũng đề cập rằng các phiên bản trong tương lai sẽ hỗ trợ nó ${KSH_MATCH[1]}
cho nhóm chụp đầu tiên. Chưa có sẵn cho đến 2017-04-25).
Tuy nhiên, với bash
, bạn có thể làm:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
Cái nào tốt hơn khi nó kiểm tra rằng mẫu được tìm thấy đầu tiên.
Nếu hỗ trợ regexps của hệ thống của bạn \s
/ \S
, bạn cũng có thể làm:
re='->\s*\S+'
[[ $var =~ $re ]]
Với zsh
, bạn có thể nhận được toàn bộ sức mạnh của PCRE với:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Với zsh -o extendedglob
, xem thêm:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Di chuyển
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Nếu có một vài lần xuất hiện của mẫu trong chuỗi, hành vi sẽ thay đổi theo tất cả các giải pháp đó. Tuy nhiên, không ai trong số họ sẽ cung cấp cho bạn một danh sách mới tất cả các kết quả trùng khớp như trong grep
giải pháp dựa trên GNU của bạn .
Để làm điều đó, bạn cần phải thực hiện vòng lặp bằng tay. Chẳng hạn, với bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Với zsh
, bạn có thể sử dụng loại mẹo này để lưu trữ tất cả các trận đấu trong một mảng:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1 tham chiếu ngược thường chỉ định một mẫu tham chiếu những gì được khớp bởi một nhóm trước đó. Chẳng hạn, \(.\)\1
biểu thức chính quy cơ bản khớp với một ký tự theo sau bởi cùng một ký tự đó (nó khớp với aa
, không bật ab
). Đó \1
là một tham chiếu ngược đến \(.\)
nhóm chụp đó trong cùng một mẫu.
ksh93
không hỗ trợ các tham chiếu ngược trong các mẫu của nó (ví dụ ls -d -- @(?)\1
sẽ liệt kê các tên tệp bao gồm hai ký tự giống nhau), chứ không phải các shell khác. Các BRE và PCRE tiêu chuẩn hỗ trợ các tham chiếu ngược nhưng không phải ERE tiêu chuẩn, mặc dù một số triển khai ERE hỗ trợ nó như một phần mở rộng. bash
là [[ foo =~ re ]]
sử dụng Eres.
[[ aa =~ (.)\1 ]]
sẽ không phù hợp, nhưng
re='(.)\1'; [[ aa =~ $re ]]
có thể nếu ERE của hệ thống hỗ trợ nó.