Bash正規表現キャプチャグループ


22

文字列から複数の英数字値(この数値は異なる場合があります)を照合し、bashキャプチャグループ配列に保存しようとしています。しかし、私は最初の一致のみを取得しています:

mystring1='<link rel="self" href="/unix//api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/unix//api/clouds/1/instances/2AAAAAAA"/>'

regex='/instances/([A-Z0-9]+)'

[[ $mystring1 =~ $regex ]]

echo ${BASH_REMATCH[1]}
1BBBBBB

echo ${BASH_REMATCH[2]}

ご覧のとおり、最初に探している値と一致しますが、2番目の値とは一致しません。


1
の出力をループすることに満足しecho "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'ますか?
ジェフシャラー

回答:


22

bashでグローバルマッチングを実行できないのは残念です。あなたはこれを行うことができます:

global_rematch() { 
    local s=$1 regex=$2 
    while [[ $s =~ $regex ]]; do 
        echo "${BASH_REMATCH[1]}"
        s=${s#*"${BASH_REMATCH[1]}"}
    done
}
global_rematch "$mystring1" "$regex" 
1BBBBBB
2AAAAAAA

これは、一致するプレフィックスを文字列から切り取り、次の部分が一致するようにすることで機能します。文字列を破壊しますが、関数ではローカル変数なので、誰が気にします。

私は実際にその関数を使用して配列を設定します:

$ mapfile -t matches < <( global_rematch "$mystring1" "$regex" )
$ printf "%s\n" "${matches[@]}"
1BBBBBB
2AAAAAAA

ありがとう-これは実行可能な解決策のように見える
...-アーサーリッセンコ

1
代替案については、mywiki.wooledge.org / BashFAQ / 001を参照してください
グレンジャックマン

6

2番目の配列値を取得するには、正規表現に2番目の括弧のセットが必要です。

mystring1='<link rel="self" href="/unix//api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/unix//api/clouds/1/instances/2AAAAAAA"/>'

regex='/instances/([A-Z0-9]+).*/instances/([A-Z0-9]+)'

[[ $mystring1 =~ $regex ]]

$ echo ${BASH_REMATCH[1]}
1BBBBBB
$ echo ${BASH_REMATCH[2]}
2AAAAAAA

ありがたいことに、私は未知の数の一致候補を探しています。
アーサーリッセンコ

1
複数の一致が配列に入ることも予想したため、Qを支持しましたが、実際には複数の括弧のセットがない限り、そうではないようです。
ジェフシャラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.