50

I'm trying to match multiple alphanumeric values (this number could vary) from a string and save them to a bash capture group array. However, I'm only getting the first match:

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]}

As you can see- it matches the first value I'm looking for, but not the second.

2
  • 2
    Would you be content with looping over the output of echo "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'?
    – Jeff Schaller
    Commented Dec 22, 2015 at 21:46
  • 10
    Probably worth mentioning the famous You can't parse HTML with regex post. Commented Dec 23, 2015 at 3:02

2 Answers 2

48

It's a shame that you can't do global matching in bash. You can do this:

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

This works by chopping the matched prefix off the string so the next part can be matched. It destroys the string, but in the function it's a local variable, so who cares.

I would actually use that function to populate an array:

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

To get the second array value, you need to have a second set of parentheses in the regex:

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
2
  • Thanks, hoever I'm looking to match an unknown number of possible matches. Commented Dec 22, 2015 at 21:36
  • 1
    I upvoted your Q because I also expected multiple matches to go into the array, but they don't seem to, unless you actually have multiple sets of parentheses.
    – Jeff Schaller
    Commented Dec 22, 2015 at 21:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .