為什麼沒有“?”正規表示式字元在 sed 中產生匹配嗎?

為什麼沒有“?”正規表示式字元在 sed 中產生匹配嗎?

我有一個類似於這裡的字串../../sdd1並嘗試匹配sdd。我正在嘗試使用以下sed命令:

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]?:\1:' 

並且它不會產生匹配。
但是當我使用

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'

然後我得到了我的比賽,sdd

我最好的猜測是我?也應該轉義,類似於大括號 - 我嘗試過並且它有效,但我不知道為什麼。

所以問題是,為什麼正規表示式與from[0-9]?不匹配,或者為什麼我們必須轉義和 大括號?1sdd1?

答案1

預設情況下,sed使用 BRE,並且需要-E或可以-r選擇使用 ERE

引用自GNU sed 手冊

在 GNU sed 中,基本正規表示式和擴展正規表示式之間的唯一區別在於一些特殊字元的行為:「?」、「+」、括號、大括號 (“{}”) 和「|」。

對於基本 (BRE) 語法,這些字元沒有特殊意義,除非前綴反斜線 ('\');而使用擴展 (ERE) 語法則相反:這些字元是特殊的,除非它們以反斜線 ('\') 為前綴。

所以,對於GNU sed,使用

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\?:\1:'
sdd
$ echo '../../sdd1' | sed -E 's:.*([a-z]{3})[0-9]?:\1:'
sdd

為了POSIX BRE,你的第二個命令就是要走的路

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'
sdd

相關內容