Bash regex gruppo di acquisizione


22

Sto cercando di far corrispondere più valori alfanumerici (questo numero potrebbe variare) da una stringa e salvarli in un array di gruppi di acquisizione bash. Tuttavia, sto ricevendo solo la prima partita:

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

Come puoi vedere, corrisponde al primo valore che sto cercando, ma non al secondo.


1
Saresti contento di fare un ciclo sull'output di echo "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'?
Jeff Schaller

4
Probabilmente vale la pena menzionare il famoso Non è possibile analizzare HTML con regex post.
Trauma digitale il

Risposte:


22

È un peccato che non si possa fare una corrispondenza globale in bash. Puoi farlo:

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

Funziona tagliando il prefisso corrispondente dalla stringa in modo da poter abbinare la parte successiva. Distrugge la stringa, ma nella funzione è una variabile locale, quindi chi se ne frega.

Vorrei effettivamente utilizzare quella funzione per popolare un array:

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

grazie- sembra una soluzione praticabile- l'unico problema è che il file di mappe non esiste in bash 3.2 ...
Arthur Lyssenko


6

Per ottenere il secondo valore di matrice, è necessario disporre di una seconda serie di parentesi nella 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

Grazie, anche se sto cercando di abbinare un numero sconosciuto di possibili corrispondenze.
Arthur Lyssenko,

1
Ho valutato la tua Q perché mi aspettavo che anche più partite andassero nell'array, ma non sembrano, a meno che tu non abbia effettivamente più set di parentesi.
Jeff Schaller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.