Bash 正则表达式捕获组

Bash 正则表达式捕获组

我试图匹配字符串中的多个字母数字值(这个数字可能会有所不同)并将它们保存到 bash 捕获组数组中。但是,我只得到第一场比赛:

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

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

[[ $mystring1 =~ $regex ]]

echo ${BASH_REMATCH[1]}
1BBBBBB

echo ${BASH_REMATCH[2]}

正如您所看到的,它与我要查找的第一个值匹配,但与第二个值不匹配。

答案1

遗憾的是你不能在 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

答案2

要获取第二个数组值,您需要在正则表达式中使用第二组括号:

mystring1='<link rel="self" href="/api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/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

相关内容