Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在Perl中,当一个正则表达式中存在两个字符串时,替换一个字符串_Regex_Perl - Fatal编程技术网

Regex 在Perl中,当一个正则表达式中存在两个字符串时,替换一个字符串

Regex 在Perl中,当一个正则表达式中存在两个字符串时,替换一个字符串,regex,perl,Regex,Perl,给定以下输入 $ cat pre stuff MACRO1 stuff MACRO2 stuff MACRO2 stuff MACRO1 stuff MACRO2 stuff 如果MACRO1也存在,我想用MACRO3替换MACRO2。像这样: $ perl -ne '/(?=.*MACRO1).*MACRO2/ ? print s/MACRO2/MACRO3/gr : print' pre stuff MACRO1 stuff MACRO3 stuff MACRO3 stuff MACRO1

给定以下输入

$ cat pre
stuff MACRO1 stuff MACRO2
stuff MACRO2 stuff MACRO1
stuff MACRO2 stuff
如果MACRO1也存在,我想用MACRO3替换MACRO2。像这样:

$ perl -ne '/(?=.*MACRO1).*MACRO2/ ? print s/MACRO2/MACRO3/gr : print' pre
stuff MACRO1 stuff MACRO3
stuff MACRO3 stuff MACRO1
stuff MACRO2 stuff
(现在我想,这个表达式的
*MACRO2
部分是不必要的) 编辑根据到目前为止的反馈,上面的一个不那么愚蠢的版本:

$ perl -ne '/MACRO1/ ? print s/MACRO2/MACRO3/gr : print' pre
我想弄明白的是如何只用一个正则表达式。这里有一个尝试:

$ perl -ne 'print s/(?=.*MACRO1)(?=.*MACRO2)MACRO2/MACRO3/gr' pre
stuff MACRO1 stuff MACRO2
stuff MACRO3 stuff MACRO1
stuff MACRO2 stuff
我想我对前瞻操作符如何同时是“锚”和“非消费”有一些基本的困惑。如果我把
?=
看作一个锚,那么我觉得上面的方法不起作用是有道理的。但这似乎与“非消费”相矛盾


有人能定义什么是非消费,并向我展示一个能够产生预期结果的正则表达式吗

首先,让我们了解实际的解决方案:

perl -pe's/MACRO2/MACRO3/g if /MACRO1/'

现在,让我们看看你的特殊要求。作为单个替换,它将类似于以下内容:

perl -pe's/MACRO2(?:(?<=MACRO1.*)|(?=.*MACRO1))/MACRO3/g'
perl-pe的/MACRO2(?(?那么总是有:

$rec =~ s/^(.*)MACRO1(.*)MACRO2(.*)$/\1MACRO1\2MACRO3\3/;
好的,根据评论(如果MACRO2排在第一位怎么办):

然后:

当然,这需要函数(我称之为foo)


在没有函数的情况下也可以这样做,在替换模式中嵌套match/replace来做同样的事情,但是我从Perl那里得到了很多语法错误(我肯定是我的错).

我想做一次替换的原因主要是为了学习。如果这是解决这个问题的一个非常愚蠢的方法,那对我来说已经足够了。我仍然有兴趣理解什么是“非消费”意思是。我的问题的这一部分有意义吗?非消费意味着从环视外部的角度来看,环视的主体被认为匹配了0个字符。例如,
“ab”=~/a(?=\w)b/
匹配,而
“ab”=~/a\wb/
不会。好吧,我认为这是有道理的。我认为让我失望的是这里投票最多的答案:。这是超级投票,所以我可能只是误解了这个答案。它肯定不像我想的那样工作。比较
'def abc'=~/^(?=.*abc)(?=.*def)/
'def abc'=~/^.*abc.*def/
*abc
匹配3个字符,但是
(?=.*abc)
匹配零个字符,所以
(?=.*def)
也开始匹配位置0。
/c(?=a)(?=b)/
是否会更清晰?记住,所有匹配之前都有一个隐式的
\a(?.s:)*?
。没有位置后面跟着
a
,后面跟着
b
。Re“如果我认为?=作为锚定”,嗯???为什么你想在一个正则表达式中完成它?将代码分解成易于消化的片段将使维护变得更容易、更快和更便宜。如果你很难理解它,那么其他人也会。这很有趣,我也很清楚。一个问题是,如果MACRO2先出现,它就不起作用。这是可以修复的吗?当然rse,可能有几种方式。但是(向你和池上春树致敬……已经有一段时间了,这很有趣)它需要一个功能:首先,向你致敬并感谢你(zzxyz)还有ikegami。已经有一段时间了,这很有趣。好吧,我在前面的2条评论中添加了进一步的编辑。为我在评论编辑中的新手身份道歉。学习。。。
sub foo {
    my ($x) = @_;
    $x =~ s/2/3/;
    return $x;
}
$s3 =~ s/^(.*)((MACRO1(.*)MACRO2)|(MACRO2(.*)MACRO1))(.*)$/$1.($3?foo($3):foo($5))/e;