perl:正则表达式帮助需要在一定条件下替换两个单词内的文本

时间:2019-04-24 12:33:47

标签: regex perl

这个问题似乎与Negative lookahead with awk or sed not possible but only perl supports相同,但并不相同。

在这个问题上,我想知道如何解决更多搜索条件

我有以下文本(sample.txt)

  

条件1:不想在QWWK和KWWQ之间包含PQXY

QWWK erly jointure  PQXY In said devonshire 
Drift allow green son walls years for blush.
acceptance son KWWQ
  

条件2:QWWK并非从该行的开头开始,所以不需要

other QWWK get him his projection ar saw fat sudden edward
sociable felicity supplied mr. September
ay now many. Alte KWWQ
  

条件3:KWWQ不在行尾,因此不需要

QWWK ble formerly six but hand
r way now many. Alteration you 
occasion ham for  KWWQ other
  

条件4:QWWK从头开始,而KWWQ在最后一个结束,并且没有PQXY,所以这就是想要的

QWWK n zealously arranging fr
eal park so rest we on. Ignorant d
he possession insensible sympathi KWWQ
.......
  

请注意单词QWWK PQXY和KWWQ

我的文字多行显示。

I want to match text between QWWK and KWWQ

Condition 1: should not contain the word PQXY inbetween

Condition 2: QWWK should start at the beginning of the line

Condition 3: KWWQ should be at the end of the line

在崇高文字中,我使用以下方式匹配:

(?s)(^QWWK(?:(?!QWWK).)*?KWWQ\n) 

它符合条件4

QWWK n zealously arranging fr

eal park so rest we on. Ignorant d

 he possession insensible sympathi KWWQ

因此它与条件1,条件2和条件3不匹配。

我正在尝试用perl将条件4替换为我正在尝试的文本

$ perl -0777pe 's/^QWWK(?!QWWK).*?KWWQ\n/sometext/gs' sample.txt > sample_mod.txt 

但是sample_mod.txt并没有取代编码4

我也尝试过

$ perl -0777pe 's/\nQWWK(?!QWWK).*?KWWQ\n/sometext/gs' sample.txt > sample_mod.txt 

它同时删除了条件1和条件4

3 个答案:

答案 0 :(得分:1)

通过反复试验,我想到了这个正则表达式:

/^QWWK(?!.*PQXY)(?!.*KWWQ[^\n])(.*?)KWWQ$/gms

/m修饰符表示输入是多行,并且^匹配 any 行的开头,$匹配 any的结尾

使用/s修饰符,.元字符表示任何字符,包括换行符

/^QWWK .../m

在行首找到以QWWK开头的子字符串

/... KWWQ$/m

,并在行尾以KWWQ结尾

/^QWWK(?!.*PQXY)/s

如果QWWK后跟任意数量的字符(包括换行符)和文本PQXY,则匹配失败。

/^QWWK ... (?!.KWWQ[^\n]) ... /s

如果QWWK后跟任意数量的字符,文本KWWQ和非换行符,则匹配也会失败。

/^QWWK(.*?)KWWQ$/s

QWWKKWWQ之间的所有文本(包括换行符)放入捕获组中。使用非贪婪修饰符?,以便正则表达式将不会尝试从早期的QWWK观察捕获到最新的KWWQ观察。

答案 1 :(得分:1)

/m^$的定义分别更改为行首和行尾。

您要的内容:

/^QWWK(?:(?!PQXY).)*KWWQ$/msg

您可能想要的东西:

/^QWWK(?:(?!QWWK|PQXY|KWWQ).)*KWWQ$/msg

已优化:(减少执行的环顾次数)

/
   ^ QWWK
   [^KPQ]*+
   (?: (?: K (?!WWQ)
       |   P (?!QXY)
       |   Q (?!WWK)
       )
       [^KPQ]*+
   )*+
   KWWQ $
/xmg

答案 2 :(得分:-1)

我读了这篇文章Multiline search replace with Perl

我尝试了以下操作,看起来很正常:

$ perl -0pe 's/^QWWK(?:(?!PQXY).)*?KWWQ\n/sometext/gms' sample.txt > sample_mod.txt 

然后仅替换条件4,其他条件保持不变