例如,我想知道\{x,y\}
in是否sed
会尝试匹配尽可能多或尽可能少的字符。
另外,有人可以向我解释以下的意外行为sed
吗?
echo "baaab" | sed 's/a\{1,2\}//'
bab
echo "baaab" | sed 's/a\{0,2\}//'
baaab
在第一行中,sed
变得贪婪,在第二行中显然没有,这是有原因的吗?
我正在使用 GNU sed 版本 4.2.1。
答案1
a\{0,2\}
将匹配行开头的空字符串(实际上,任何空字符串,但未g
指定):
$ echo "baaab" | sed 's/a\{0,2\}/y/'
ybaaab
由于 GNUsed
从左到右进行匹配,并且未指定全局替换,因此仅匹配行的开头。如果您使用过g
:
$ echo "baaab" | sed 's/a\{0,2\}/y/g'
ybyyby
开头和结尾的空字符串匹配,并且aa
、 和剩余的a
。
答案2
是的,就是贪心。
在 POSIX 兼容系统中,不仅sed
包括所有使用的工具基本正则表达式, 这匹配的模式永远是贪婪的:
对匹配序列的搜索从字符串的开头开始,并在找到与表达式匹配的第一个序列时停止,其中“first”被定义为表示“在字符串中最早开始”。如果模式允许可变数量的匹配字符,因此从该点开始有多个这样的序列,匹配最长的此类序列。例如,BRE“bb*”匹配字符串“abbbc”的第二到第四个字符,ERE“(wee|week)(knights|night)”匹配字符串“weeknights”的所有十个字符。
与整个匹配是最左边匹配中最长的匹配一致,每个子模式从左到右应匹配最长的可能字符串。以此目的,空字符串应被视为比根本不匹配更长。例如,匹配 BRE“(.)。” 与“abcdef”匹配,子表达式“(\1)”是“abcdef”,并且与“bc”匹配 BRE“(a*)*”,子表达式“(\1)”是空字符串。
该模式匹配零到二之间的a\{0,2\}
任何字符出现。a
零次出现意味着空字符串,它被认为比上面指定的规范中不匹配的长度要长。
您的使用问题是您没有使用ubstitution 命令g
的 lobal 标志sed
s
。如果没有g
lobal 标志,一旦找到第一个匹配项(即行开头的空字符串)就sed
停止替换。s
一般形式是\{m,n\}
with 0 <= m <= n <= RE_DUP_MAX
, with在大多数平台上RE_DUP_MAX
都是:32767
$ getconf RE_DUP_MAX
32767