Bashを使った怠惰な正規表現

Bashを使った怠惰な正規表現

Bashに組み込まれている正規表現機能を使用して、HTMLタグに含まれるテキストのみを一致させようとしています。

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を使用してください。そのタスク用に設計されたツールの1つを使用するのはどうですか?

=~とにかく、私が知っている限り、非欲張りな一致を実行するために演算子を使用する方法はありません。これは、bashの内部正規表現エンジンを使用せず、次のman 3 regexようにシステムのCエンジンを使用するためです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

関連情報