
我有一個類似於這裡的字串../../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]?
不匹配,或者為什麼我們必須轉義和 大括號?1
sdd1
?
答案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