Estoy tratando de hacer coincidir solo el texto contenido en las etiquetas HTML usando la función de expresiones regulares incorporada de Bash:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>(.+?)</span>'
[[ $string =~ $regex ]]
echo "${BASH_REMATCH[1]}"
Pero el partido sigue capturando foo</span>
.
Internet está tan lleno de ejemplos de sed y grep que no he encontrado mucha documentación sobre la propia expresión regular de Bash.
Respuesta1
Hay una razón por la cual Internet está repleto de enfoques alternativos. Realmente no puedo pensar en ninguna situación en la que estaríasforzadousar bash para esto. ¿Por qué no utilizar una de las herramientas diseñadas para el trabajo?
De todos modos, hasta donde yo sé, no hay forma de hacer coincidencias no codiciosas usando el =~
operador. Esto se debe a que no utiliza el motor de expresiones regulares interno de bash, sino el motor C de su sistema, tal como se define en man 3 regex
. Esto se explica en 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)).
Sin embargo, puedes hacer más o menos lo que quieras (teniendo en cuenta que esto es realmentenouna buena forma de analizar archivos HTML) con una expresión regular ligeramente diferente:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>([^<]+)</span>'
[[ $string =~ $regex ]];
echo "${BASH_REMATCH[1]}"
Lo anterior volverá foo
como se esperaba.
Respuesta2
No sé si las expresiones regulares de bash coinciden con coincidencias no codiciosas como Perl, así que use un motor de expresiones regulares de Perl:
$ grep -oP '<span class="circle"> </span>\K.+?(?=</span>)' <<<"$string"
foo