我有一个这样的文档:
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.
AAAAAA
和 ZZZZZZ
与 {
和 }
类似,但用于避免其他问题可能将 {
和 }
解释为其他含义的脚本。
当在 AAAAAA
和 ZZZZZZ
之间找不到“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"
当在某些匹配的符号集之间找不到任何模式时,如何删除它?
最佳答案
您有几种可能的方法:
您可以使用
\K
从匹配结果中删除您不想要的部分的功能:s/AAAAAA.*?ZZZZZZ\K|cat//gs
(
\K
从匹配结果中删除左侧的所有字符,但左侧的所有字符都会被正则表达式引擎消耗。结果,当交替的第一部分成功时,您将替换空字符串(紧接在 ZZZZZZ 之后)和一个空字符串。)您可以使用capturing group注入(inject)您想要在替换字符串中保留的子字符串(使用引用
$1
):s/(AAAAAA.*?ZZZZZZ)|cat/$1/gs
您可以使用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/