Grupa przechwytywania wyrażeń regularnych Bash

22

Próbuję dopasować wiele wartości alfanumerycznych (liczba ta może się różnić) z ciągu i zapisać je w tablicy grup przechwytywania bash. Jednak dostaję tylko pierwszy mecz:

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

Jak widać - odpowiada pierwszej szukanej wartości, ale nie drugiej.

Arthur Lyssenko
źródło
1
Czy byłbyś zadowolony z zapętlania wyników echo "$mystring1" | grep -oE '/instances/([A-Z0-9]+)'?
Jeff Schaller
4
Prawdopodobnie warto wspomnieć o słynnym Nie można parsować HTML postem regularnym .
Cyfrowy uraz

Odpowiedzi:

22

Szkoda, że ​​nie można dopasowywać globalnie w bash. Możesz to zrobić:

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

Działa to poprzez odcięcie dopasowanego prefiksu od łańcucha, aby można było dopasować następną część. Niszczy ciąg, ale w funkcji jest zmienną lokalną, więc kogo to obchodzi.

Używałbym tej funkcji do wypełnienia tablicy:

$ mapfile -t matches < <( global_rematch "$mystring1" "$regex" )
$ printf "%s\n" "${matches[@]}"
1BBBBBB
2AAAAAAA
Glenn Jackman
źródło
dzięki - to wygląda na realne rozwiązanie - jedynym problemem jest brak
pliku map
1
Zobacz mywiki.wooledge.org/BashFAQ/001 dla alternatyw
glenn jackman
6

Aby uzyskać drugą wartość tablicy, musisz mieć drugi zestaw nawiasów w wyrażeniu regularnym:

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
Jeff Schaller
źródło
Dzięki, hoever, chcę dopasować nieznaną liczbę możliwych dopasowań.
Arthur Lyssenko,
1
Poparłem twoje pytanie, ponieważ spodziewałem się, że do tablicy trafi też wiele dopasowań, ale wydaje się, że nie, chyba że faktycznie masz wiele zestawów nawiasów.
Jeff Schaller