O shell bash
, por si só, fornece uma maneira de fazer o processo de correspondência de expressão regular dos grupos capturados, conforme necessário.
O operador =~
dentro de uma expressão de teste de colchetes duplos, [[
com a cadeia de correspondência no lado esquerdo do operador e a expressão regular como o operando da direita.
if [[ "$str" =~ $re ]]; then
Se a expressão corresponder à string, a parte correspondente da string será armazenada na matriz BASH_REMATCH
, que pode ser colocada em loop para acessar os grupos capturados individuais. O status de saída é 0
se o regexp corresponder, 1
se isso não ocorrer e 2
se a expressão for inválida.
No que diz respeito ao seu exemplo, supondo que você tenha as linhas de entrada armazenadas em uma matriz e as palavras blah
e hello
sejam padrões fixos
#!/usr/bin/env bash
exampleStr=('blah12687hello=123' 'nothingthatmatches' 'blah3211hello=123456' 'blah15butnottheotherpattern')
re='blah([[:digit:]]+)hello=([[:digit:]]+)'
for str in "${exampleStr[@]}"; do
if [[ "$str" =~ $re ]]; then
for group in "${BASH_REMATCH[@]}"; do
printf "%s\n" "$group"
done
else
printf "No match \n"
fi
done
Como você pode ver no código acima, uma vez que correspondamos a expressão regular para ser verdade, podemos percorrer a matriz BASH_REMATCH
para imprimir cada um dos grupos capturados. A saída geral do script seria algo como
blah12687hello=123 # Value of BASH_REMATCH[0]
12687 # Value of BASH_REMATCH[1]
123 # Value of BASH_REMATCH[2]
Regex not matches.
blah3211hello=123456
3211
123456
Regex not matches.
Como você pode ver, o BASH_REMATCH[0]
sempre contém a parte da string que foi correspondida com sucesso pelo regex, e os grupos capturados individuais podem ser acessados a partir do índice 1
em diante. Você pode escrever uma lógica personalizada para processar cada grupo capturado, que é o que você originalmente pretendia fazer.
Se você estiver interessado em ler uma entrada de arquivo, use um loop while
com redirecionamento de entrada no arquivo a ser processado
while IFS= read -r line; do
if [[ "$line" =~ $re ]]; then
for group in "${BASH_REMATCH[@]}"; do
printf "%s\n" "$group"
done
else
printf "No match \n"
fi
done < inputFile.txt