perl
我正在尝试对命令行中的匹配模式使用一些算术。我可以在一场比赛中做到这一点,但不能在所有比赛中做到这一点。
str="a1b2c3"
perl -pe 's/\d+/$&+1/e' <<<"$str"
a2b2c3
我理解这里$&
指的是第一个匹配的数字1
。我需要做什么才能将1
所有数字相加?是否有一个类似的变量$&
代表所有匹配的模式?或者需要修改正则表达式以匹配多个数字。
对于给定的输入,我期望输出类似
a2b3c4
答案1
str="a1b2c3"
perl -pe 's/\d+/$&+1/ge' <<<"$str"
g
替换的标志将使 Perl 对输入行上的每个非重叠匹配应用表达式。
挑剔:实际上这里不涉及捕获组(最初的问题提到了捕获组)。 Perl 变量$&
是“最后一次成功的模式匹配所匹配的字符串”。这与eg$1
和etc不同$2
,后者引用与相应捕获组(括号表达式)匹配的字符串。中没有捕获组\d+
,但您可以使用它s/(\d+)/$1+1/ge
来代替,它确实使用单个捕获组。
就结果而言,s/(\d+)/$1+1/ge
和之间没有区别。s/\d+/$&+1/ge
在这个简短的内联 Perl 脚本中,无论您选择使用其中一种还是另一种都没有区别,但通常您希望避免$&
在执行许多正则表达式操作的较长 Perl 程序中使用,至少在使用较旧的 Perl 时是如此发布。
来自perldoc perlvar
(我的重点):
性能问题
传统上,在 Perl 中,在代码中的任何位置使用这三个变量中的任何一个或 (或其等效项)
$`
,$&
$'
use English
导致所有后续成功的模式匹配都会生成匹配字符串的副本,以防代码随后访问这些变量之一。这对整个程序造成了相当大的性能损失,因此通常不鼓励使用这些变量。[...]
在 Perl 5.20.0 中,默认启用新的写时复制系统,最终解决了这三个变量的所有性能问题,并使它们可以在任何地方安全使用。
答案2
如果您实际上正在使用zsh
shell(<<<
是一个非标准运算符,确实来自zsh
,但此后已被复制到其他几个 shell),请注意您不需要perl
为此调用。
你可以做:
set -o extendedglob # for (#m) below
printf '%s\n' ${str//(#m)<->/$((MATCH+1))}
在哪里
(#m)
打开对整个比赛的捕获$MATCH
(相当于perl
s$&
)<->
匹配任何十进制数字序列(类似于<5-12>
但没有任何限制)。