52

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

50

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.