Ленивое регулярное выражение с использованием Bash

Ленивое регулярное выражение с использованием Bash

Я пытаюсь сопоставить только текст, содержащийся в тегах 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

Связанный контент