比较:
echo 'abc def' | sed 's/\([a-zA-Z0-9][a-zA-Z0-9]+\) \([a-zA-Z0-9][a-zA-Z0-9]+\)/\2 \1/'
abc def
echo 'abc def' | sed 's/\([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\)/\2 \1/'
def abc
echo 'abc def' | sed 's/\([a-zA-Z0-9]+\) \([a-zA-Z0-9]+\)/\2 \1/'
abc def
echo 'abc def' | sed 's/\([a-zA-Z0-9]*\) \([a-zA-Z0-9]*\)/\2 \1/'
def abc
目的是交换“abc”和“def”,为什么其中一些示例不起作用?
在 + 版本中:我预期 [a-zA-Z0-9]+ 会匹配“a”、“ab”和“abc”(直到空格)并交换它们。我预期 [a-zA-Z0-9][a-zA-Z0-9]+ 版本会匹配“ab”和“abc”,这样就可以
除了单个版本之外,* 版本之间还有什么区别吗?
[a-zA-Z0-9][a-zA-Z0-9]* 和 [a-zA-Z0-9]+ 不是一样吗?即匹配至少一个字母数字字符的字符串?
答案1
sed 使用的 POSIX“基本”正则表达式语言没有+
运算符,因此[a-zA-Z0-9]+
只匹配一个字母数字字符 - 后跟一个文字加号。
它确实有\{x,y\}
运算符来接受指定数量的匹配,例如:
$ echo 'abc def' | sed 's/\([a-zA-Z0-9]\{2,\}\) \([a-zA-Z0-9]\{2,\}\)/\2 \1/'
def abc
用于sed -E
启用“扩展”正则表达式模式,其中+
是特殊字符。这也会改变括号的工作方式 - 在扩展模式下,空括号(
)
用于捕获组,同样空括号{
}
用于匹配数,与基本模式相反。
$ echo 'abc def' | sed -E 's/([a-zA-Z0-9][a-zA-Z0-9]+) ([a-zA-Z0-9][a-zA-Z0-9]+)/\2 \1/'
def abc
$ echo 'abc def' | sed -E 's/([a-zA-Z0-9]{2,}) ([a-zA-Z0-9]{2,})/\2 \1/'
def abc
GNU sed/grep 也允许您在基本模式下使用\+
,但这无法移植到其他操作系统。请参阅info "(sed)BRE syntax"
和info "(sed)ERE syntax"
(或man 7 regex
)以比较这两种模式。