在Perl中,当模式包含带括号的加法时,为什么我的正则表达式替换失败?

时间:2017-06-14 19:50:22

标签: regex perl

我在一个非常基本的perl sed操作上磕磕绊绊。无法弄清问题在哪里。在我的程序中的某个时刻,我有一个字符串,其中包含以下行:

my $line = "(l_extendedprice*(THISISREPLACED)*(1+l_tax))";

my $substitute = "(1+l_tax)";

if($line=~ /$substitute/){
$line =~ s/$substitute/matched/;
}

观察输出:

(l_extendedprice*(THISISREPLACED)*(1+l_tax))

期望的输出:

(l_extendedprice*(THISISREPLACED)*(matched))

更新

$ line和$substitute的值是从代码的一部分生成的。那么,有没有办法处理*+而不会将$substitute分成几部分?

3 个答案:

答案 0 :(得分:2)

匹配和替换运算符期望正则表达式模式。

正则表达式模式(1+l_tax)与字符串(1+l_tax)不匹配。

正则表达式模式\(1\+l_tax\)是仅匹配字符串(1+l_tax)的模式。

您可以使用该字符串上的quotemeta来获取与特定字符串匹配的模式。

my $substr_re = quotemeta($substr);
if ($string =~ /$substr_re/) { ... }

您可以在预期正则运算符中使用\Q..\E作为quotemeta的快捷方式。

if ($string =~ /\Q$substr\E/) { ... }

\E是可选的,如果它位于文字的末尾。

if ($string =~ /\Q$substr/) { ... }

在您的情况下,您需要首先将$substitute修改为您要替换的字符串。

my $substitute = "1+l_tax";

然后,你可以使用我之前展示的内容来匹配并替换它。

if ($line =~ /\Q$substitute/) {
    $line =~ s/\Q$substitute/matched/;
}

简化为以下内容:

$line =~ s/\Q$substitute/matched/;

答案 1 :(得分:1)

你有

if($line=~ /$substitute/){

然后在正则表达式匹配中使用

1+

但是,当然,(...)表示" 匹配字符串"中的一个或多个1。此外,my $line = "(l_extendedprice*(THISISREPLACED)*(1+l_tax))"; my $substitute = "(1+l_tax)"; $line =~ s/\Q$substitute/matched/; 表示捕获。因此,您需要转义那些在正则表达式模式中具有特殊含义的字符。

此外,您不需要先匹配替换:

$line =~ s/.../.../

注意$line = s/.../.../而不是$line。后者(这是您在代码中使用它的方式)会将$_ =~ s/.../.../中的值替换为router.get("/browse", function(req, res, next){ // Get all stories from DB Story.find({}, function(err, allStories){ if (err) { return next(err); } else { // if user is logged in then render stories and any alerts if(req.user) { User.findById(req.user._id).populate({ path: 'alerts', model: 'Alert', match: { 'isRead': { $eq: false }} }).exec(function(err, user) { if(err) { return next(err); } res.render("stories/index", {stories:allStories, alerts: user.alerts.length, page: 'browse'}); }); } else { res.render("stories/index", {stories:allStories}) } } }) }) 的结果。

答案 2 :(得分:-2)

逃避+号。

$ cat test.groovy
myStr = "hello World!"
$
$ groovysh
groovy:000> load test.groovy
===> hello World!
groovy:000> println myStr
hello World!
===> null
groovy:000>