Regex preguiçoso usando Bash

1

Estou tentando corresponder apenas o texto contido nas tags HTML usando a função de 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.

    
por saltface 07.05.2014 / 21:05

2 respostas

7

Existe uma razão pela qual a Internet está repleta de abordagens alternativas. Eu não consigo pensar em qualquer situação em que você seria forçado a usar 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 correspondências não-gananciosas usando o operador =~ . Isso porque ele não usa o mecanismo de regex interno do bash, mas o 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 não é realmente não uma boa maneira de analisar arquivos HTML) com um regex ligeiramente diferente:

string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>([^<]+)</span>'
[[ $string =~ $regex ]]; 
echo "${BASH_REMATCH[1]}"

Os itens acima retornarão foo conforme o esperado.

    
por 07.05.2014 / 22:08
3

Eu não sei se as expressões regulares do bash para correspondência não-gananciosa como Perl, então use um mecanismo de regex Perl:

$ grep -oP '<span class="circle"> </span>\K.+?(?=</span>)' <<<"$string"
foo
    
por 07.05.2014 / 21:11