Perl正则表达式命令行问题

jgzswidk  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(143)

我尝试在命令行中使用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)中试过,它工作正常,所以我不确定为什么它在这里不工作

s6fujrry

s6fujrry1#

在Bash中,!是“历史扩展字符”,除非用反斜杠或单引号转义(双引号 * 不 * 禁用此功能;也就是说,支持在双引号内展开历史记录。请参阅Difference between single and double quotes in Bash
因此,只需将双引号改为单引号:

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

瞧:

1.41.2
kt06eoxx

kt06eoxx2#

我猜下面这个表达式也可以:

([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.(第一个字母)
nbnkbykc

nbnkbykc3#

如果您想“increment”一个数字,那么您不能硬编码新的值,但需要捕获那里的内容并递增它

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

这里/e修饰符使得替换的一方作为代码来计算,我们可以+1捕获的数字,然后替换。\K丢弃先前的匹配,所以我们不需要把它们放回去;请参阅perlre中扩展模式中的“*LookaroundAssert *”。
有时候,查看器正是你想要的,但是它们增加了正则表达式的复杂性(仅仅是因为它们存在),可能很难得到正确的结果,并且降低了效率。
您得到的奇怪输出是因为Perl程序周围使用的双引号“邀请”shell查看内部内容,从而将!解释为历史扩展并运行它,如ruakh的帖子中所解释的那样。

f1tvaqid

f1tvaqid4#

作为lookahead的替代方法,我们可以使用捕获组,例如,下面将把版本号捕获到3个捕获组中。

(\d+)\.(\d+)\.(\d+)

如果要按原样输出捕获的版本号,则应为:

\1.\2.\3

如果用数字“2”替换第三部分,则为:

\1.\2.2

为了适应OP的问题,它将是:

$ echo 1.14.1 | perl -pe 's/(\d+)\.(\d+)\.(\d+)/\1.\2.2/'
1.14.2
$

相关问题