Perl Regex命令行问题

时间:2019-06-19 04:25:16

标签: regex bash perl

我试图在命令行中的perl中使用负前瞻:

echo 1.41.1 | perl -pe "s/(?![0-9]+\.[0-9]+\.)[0-9]$/2/g"

获得如下所示的增量版本:

1.41.2

但它只是让我回来:

![0-9]+\.[0-9]+\.: event not found

我已经在regex101(PCRE)中尝试过,并且效果很好,所以我不确定为什么它在这里不起作用

3 个答案:

答案 0 :(得分:6)

在Bash中,!是“ history expansion字符”,但用反斜杠或单引号引起来的除外。 (双引号不会 not 禁用此功能;也就是说,双引号内支持历史记录扩展。请参见Difference between single and double quotes in Bash

因此,只需将双引号更改为单引号:

echo 1.41.1 | perl -pe 's/(?![0-9]+\.[0-9]+\.)[0-9]$/2/g'

和voilà:

1.41.2

答案 1 :(得分:5)

如果您想“ 增加”一个数字,则无法对新值进行硬编码,而需要捕获其中的值并对其进行递增

echo "1.41.1" | perl -pe's/[0-9]+\.[0-9]+\.\K([0-9]+)/$1+1/e'

在这里/e修饰符使得替换面被评估为代码,我们可以+1捕获的数字,然后替换。 \K放弃了之前的比赛,因此我们不需要放回原先的比赛;请参阅“ 环顾四周断言in Extended Patterns in perlre

环视有时只是您想要的东西,但是它们总是会大大增加正则表达式的复杂性(仅靠在那儿),可能会变得棘手,从而影响效率。这里不需要它们。

您得到的奇怪输出是因为Perl程序周围使用的双引号“邀请”外壳程序查看其中的内容,从而将!解释为历史扩展并运行它,如ruakh的帖子所述。

答案 2 :(得分:4)

我猜这个表达式也可能起作用:

([0-9.]+)\.([0-9]+)

测试

perl -e'
    my $name = "1.41.1";
    $name =~ s/([0-9.]+)\.([0-9]+)/$1\.2/;
    print "$name\n";
    '

输出

1.41.2

Please see the demo here.