regex - 在 Perl 中的两个符号之间找不到模式时如何删除模式?

标签 regex perl

我有一个这样的文档:

Once upon a time, there lived a cat.
The AAAAAA cat was ZZZZZZ very happy.
The AAAAAAcatZZZZZZ knew many other cats from many AAAAAA cities ZZZZZZ.
The cat knew brown cats and AAAAAA green catsZZZZZZ and red cats.

AAAAAAZZZZZZ{} 类似,但用于避免其他问题可能将 {} 解释为其他含义的脚本。

当在 AAAAAAZZZZZZ 之间找不到“cat”时,我需要删除所有出现的“cat”。

Once upon a time, there lived a .
The AAAAAA cat was ZZZZZZ very happy.
The AAAAAAcatZZZZZZ knew many other s from many AAAAAA cities ZZZZZZ.
The  knew brown s and AAAAAA green catsZZZZZZ and red s.
  • 所有 AAAAAA 都有一个匹配的 ZZZZZZ
  • AAAAAA 和匹配的 ZZZZZZ 不会跨行分割。
  • AAAAAA 和匹配的 ZZZZZZ 永远不会嵌套。
  • 上例中的模式“cat”不被视为单词。这可以是任何东西。

我尝试了几件事,例如:

perl -pe 's/[^AAAAAAA](.*)(cat)(.*)[^BBBBBBB]//g' <<< "AAAAAAA cat 1 BBBBBBB cat 2"

当在某些匹配的符号集之间找不到任何模式时,如何删除它?

最佳答案

您有几种可能的方法:

  1. 您可以使用\K从匹配结果中删除您不想要的部分的功能:

    s/AAAAAA.*?ZZZZZZ\K|cat//gs
    

    (\K 从匹配结果中删除左侧的所有字符,但左侧的所有字符都会被正则表达式引擎消耗。结果,当交替的第一部分成功时,您将替换空字符串(紧接在 ZZZZZZ 之后)和一个空字符串。)

  2. 您可以使用capturing group注入(inject)您想要在替换字符串中保留的子字符串(使用引用 $1):

    s/(AAAAAA.*?ZZZZZZ)|cat/$1/gs
    
  3. 您可以使用backtracking control verbs跳过并且不重试匹配的子字符串:

    s/AAAAAA.*?ZZZZZZ(*SKIP)(*FAIL)|cat//gs
    

    ((*SKIP) 强制正则表达式引擎在模式稍后失败时不重试左侧找到的子字符串。(*FAIL) 强制失败的模式。)

注意:如果 AAAAAA 和 ZZZZZZ 必须始终在同一行,您可以删除 /s modifier并逐行处理数据。

关于regex - 在 Perl 中的两个符号之间找不到模式时如何删除模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23889697/

相关文章:

java - 如何确定一个数字是否是正则表达式的素数?

ios - 在 iOS 中查找字符串中的标签

java - Tomcat、Jetty 或其他网络服务器以将 Java 应用程序作为服务运行

正则表达式匹配引号中的一个词或多个词

c#从字符串中提取多个数字

java - 正则表达式查找除数字后面的所有字符

perl - 为什么用 "our"声明的变量在文件中可见?

arrays - 从 perl 模块文件访问全局数组

perl - 如何在污点模式下使用 File::Find::Rule?

perl - 在 Perl 中,如何确定是否存在标准输入?