Я пытаюсь сопоставить только текст, содержащийся в тегах HTML, используя встроенную функцию регулярных выражений Bash:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>(.+?)</span>'
[[ $string =~ $regex ]]
echo "${BASH_REMATCH[1]}"
Но матч продолжает захватывать foo</span>
.
Интернет настолько переполнен примерами использования sed и grep, что я не нашел достаточной документации по собственному регулярному выражению Bash.
решение1
Недаром в Интернете полно альтернативных подходов. Я не могу представить себе ни одной ситуации, в которой вы быпринужденныйиспользовать bash для этого. Почему бы не использовать один из инструментов, разработанных для этой работы?
В любом случае, насколько я знаю, нет способа делать нежадные совпадения с помощью =~
оператора. Это потому, что он не использует внутренний движок регулярных выражений bash, а использует C-движок вашей системы, как определено в man 3 regex
. Это объясняется в 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)).
Однако вы можете делать более или менее то, что хотите (имея в виду, что это действительнонетхороший способ анализа HTML-файлов) с немного другим регулярным выражением:
string='<span class="circle"> </span>foo</span></span>'
regex='<span class="circle"> </span>([^<]+)</span>'
[[ $string =~ $regex ]];
echo "${BASH_REMATCH[1]}"
Вышеуказанное вернется, foo
как и ожидалось.
решение2
Я не знаю, поддерживают ли регулярные выражения bash нежадное сопоставление, как в Perl, поэтому используйте механизм регулярных выражений Perl:
$ grep -oP '<span class="circle"> </span>\K.+?(?=</span>)' <<<"$string"
foo