Grupo de captura de regex de bash


22

Estou tentando corresponder vários valores alfanuméricos (esse número pode variar) de uma string e salvá-los em uma matriz de grupo de captura bash. No entanto, estou conseguindo apenas a primeira partida:

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

Como você pode ver, ele corresponde ao primeiro valor que estou procurando, mas não ao segundo.


1
Você ficaria satisfeito com o loop sobre a saída de echo "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'?
Jeff Schaller

4
Provavelmente vale a pena mencionar o famoso Você não pode analisar o HTML com o regex post.
Digital Trauma

Respostas:


22

É uma pena que você não possa fazer uma correspondência global no bash. Você consegue fazer isso:

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

Isso funciona cortando o prefixo correspondente da string para que a próxima parte possa ser correspondida. Destrói a string, mas na função é uma variável local, então quem se importa.

Na verdade, eu usaria essa função para preencher uma matriz:

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

obrigado- isso parece uma solução viável - apenas o arquivo de mapfile não existe no bash 3.2 ...
Arthur Lyssenko


6

Para obter o segundo valor da matriz, você precisa ter um segundo conjunto de parênteses na regex:

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

Obrigado, estou procurando combinar um número desconhecido de possíveis correspondências.
Arthur Lyssenko

1
Votou seu Q porque eu também esperava que várias correspondências fossem inseridas na matriz, mas elas não parecem, a menos que você realmente tenha vários conjuntos de parênteses.
Jeff Schaller
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.