使用 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。為什麼不使用專為這項工作設計的工具之一呢?

無論如何,據我所知,沒有辦法使用=~運算符進行非貪婪匹配。這是因為它不使用 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

相關內容