【问题标题】:Perl Regex Command Line IssuePerl 正则表达式命令行问题
【发布时间】:2019-06-19 04:25:16
【问题描述】:

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

【问题讨论】:

标签: regex bash perl


【解决方案1】:

在 Bash 中,! 是“history expansion 字符”,除非使用反斜杠或单引号进行转义。 (双引号禁用此功能;也就是说,双引号内支持历史扩展。请参阅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

【讨论】:

  • 您也可以通过set +H 在当前shell 中禁用! 历史扩展。而shopt -s histreedit 将允许您编辑失败的历史扩展,而不是仅仅丢弃键入的命令。
【解决方案2】:

我猜这个表达式也可能有效:

([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.

【讨论】:

  • 谢谢艾玛!这可行,但单引号将是更直接的路线。
  • @Allen 嗯,你也有单引号......但这里真的不需要环顾四周
【解决方案3】:

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

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

这里/e修饰符使得替换端被评估为代码,我们可以+1捕获的数字,然后替换。 \K 删除以前的匹配项,因此我们不需要将它们放回去;请参阅“Lookaround Assertionsin Extended Patterns in perlre

环顾四周有时正是您想要的,但它们增加了正则表达式的复杂性(只是在那里),可能很难正确处理,并且会降低效率。这里不需要它们。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多