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;