正则解释:[a-zA-Z0-9][a-zA-Z0-9] 与 [a-zA-Z0-9] 之间的区别,其中 * 与 +

正则解释:[a-zA-Z0-9][a-zA-Z0-9] 与 [a-zA-Z0-9] 之间的区别,其中 * 与 +

比较:

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)以比较这两种模式。

相关内容