为什么没有“?”正则表达式字符在 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

相关内容