web-dev-qa-db-fra.com

Groupe de capture de regex bash

J'essaie de faire correspondre plusieurs valeurs alphanumériques (ce nombre peut varier) à partir d'une chaîne et de les enregistrer dans un tableau de groupe de capture bash. Cependant, je n'obtiens que le premier 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]}

Comme vous pouvez le voir, cela correspond à la première valeur que je recherche, mais pas à la seconde.

23
Arthur Lyssenko

C'est dommage que vous ne puissiez pas faire de correspondance globale dans bash. Tu peux le faire:

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

Cela fonctionne en coupant le préfixe correspondant de la chaîne afin que la partie suivante puisse être mise en correspondance. Il détruit la chaîne, mais dans la fonction, c'est une variable locale, alors peu importe.

J'utiliserais en fait cette fonction pour remplir un tableau:

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

Pour obtenir la deuxième valeur du tableau, vous devez avoir un deuxième ensemble de parenthèses dans l'expression régulière:

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
7
Jeff Schaller

Implémentation de Python:

def getall(mysentence):
    regex = re.compile(r'.*?/instances/([0-9A-Z]+)')
    result = regex.findall(mysentence)
    return result

print(getall('<link rel="self" href="/api/clouds/1/instances/1BBBBBB"/> dsf <link rel="self" href="/api/clouds/1/instances/2AAAAAAA"/>'))
0
ADEMILOLA ALADETAN