Estou tentando corresponder apenas o texto contido nas tags HTML usando a função regex integrada do Bash:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>(.+?)</span>'
[[ $string =~ $regex ]]
echo "${BASH_REMATCH[1]}"
Mas a partida continua capturando foo</span>
.
A internet está tão cheia de exemplos de sed e grep que não encontrei muita documentação sobre o regex do próprio Bash.
Responder1
Há uma razão pela qual a Internet está repleta de abordagens alternativas. Eu realmente não consigo pensar em nenhuma situação em que você estariaforçadousar o bash para isso. Por que não usar uma das ferramentas projetadas para o trabalho?
De qualquer forma, até onde eu sei não há como fazer partidas não gananciosas usando o =~
operador. Isso ocorre porque ele não usa o mecanismo regex interno do bash, mas o mecanismo C do seu sistema, conforme definido em man 3 regex
. Isso é explicado em man bash
:
An additional binary operator, =~, is available, with the same prece‐
dence as == and !=. When it is used, the string to the right of the
operator is considered an extended regular expression and matched
accordingly (as in regex(3)).
Você pode, no entanto, fazer mais ou menos o que quiser (tendo em mente que isso é realmentenãouma boa maneira de analisar arquivos HTML) com uma regex ligeiramente diferente:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>([^<]+)</span>'
[[ $string =~ $regex ]];
echo "${BASH_REMATCH[1]}"
O acima retornará foo
conforme o esperado.
Responder2
Não sei se as expressões regulares do bash correspondem a uma correspondência não gananciosa como Perl, então use um mecanismo regex Perl:
$ grep -oP '<span class="circle"> </span>\K.+?(?=</span>)' <<<"$string"
foo