regex - 当 Perl 中的一个正则表达式中存在两个字符串时替换字符串

标签 regex perl

鉴于以下输入

$ cat pre
stuff MACRO1 stuff MACRO2
stuff MACRO2 stuff MACRO1
stuff MACRO2 stuff

如果 MACRO1 也存在,我想替换 MACRO2(用 MACRO3)。像这样:
$ 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

我想我对前瞻运算符如何同时成为“ anchor ”和“非消耗”存在一些根本性的困惑。如果我想 ?=作为主播,我认为上述方法不起作用是有道理的。但这似乎与“非消费”相矛盾。

任何人都可以定义非消耗的含义并向我展示一个可以产生所需结果的正则表达式吗?

最佳答案

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

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

现在,让我们看看您的特殊要求。作为单个替换,它看起来类似于以下内容:
perl -pe's/MACRO2(?:(?<=MACRO1.*)|(?=.*MACRO1))/MACRO3/g'

忽略这不起作用的事实,因为不支持可变宽度的lookbehinds,这是非常低效的。虽然我提出的第一个解决方案所需的时间受文件大小因素的限制,但此解决方案所需的时间受文件大小因素乘以 MACRO2 实例数量因素的限制!

关于regex - 当 Perl 中的一个正则表达式中存在两个字符串时替换字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45762836/

相关文章:

Java:使用正则表达式拆分字符串而不删除定界符

c++ - 在 C++11 中使用正则表达式回顾

Javascript正则表达式匹配字符串

perl - 如何在 Perl 中使多个变量只读?

perl - 无法处理 perl LDAP 搜索

regex - 如何使用 perl 正则表达式查找不包含冒号符号的文本行

Java 扫描器定界符用法

ios - 匹配正则表达式时获取单个元素

regex - perl oneliner + 如何过滤文件

perl - Perl 中的虚拟文件系统