【问题标题】:How to delete a pattern when it is not found between two symbols in Perl?在 Perl 中的两个符号之间找不到模式时如何删除?
【发布时间】:2014-05-27 12:40:14
【问题描述】:

我有一个这样的文件:

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 之间找不到“猫”,我需要删除它的所有外观。

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"

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

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    你有几种可能的方法:

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

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

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

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

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

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

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

    注意:如果AAAAAA和ZZZZZZ必须一直在同一行,可以去掉/smodifier,逐行处理数据。

    【讨论】:

    • 非常友好和彻底地展示所有这些选项,+1 :)
    • @zx81:谢谢你的鼓励!
    • 感谢您时常您的鼓励和 cmets,哦,正则表达式大师。 :)
    猜你喜欢
    • 2019-09-14
    • 1970-01-01
    • 2013-08-24
    • 2021-10-15
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    相关资源
    最近更新 更多