我正在尝试创建一个执行以下操作的正则表达式:
匹配( pattern1 )后跟任何包括新行的内容,只要它不包含( pattern2 )
我认为很接近的几个是:
test[\s\S]+(!notme)
或
test.*(!notme)
我最终在perl
做这个,但我正在这个网站上测试:
http://www.myregextester.com/index.php
任何帮助都将不胜感激。
答案 0 :(得分:4)
首先,关键是(?:(?!STRING).)*
到STRING
,[^CHAR]*
到CHAR
。
我认为您要确保pattern2
不关注pattern1
。如果是这样,你可以使用上面的"技巧"得到
/pattern1(?:(?!pattern2).)*\z/s
在这种情况下,您可以将其简化为
/pattern1(?!.*pattern2)/s
如果您真正想要的是捕获所有跟进的字符,直到pattern2
或字符串结尾,您可以使用
my ($following) = /pattern1((?:(?!pattern2).)*)/s;
有些人可能会推荐以下内容,但我讨厌使用?
量词修饰符。它太脆弱了。
my ($following) = /pattern1(.*?)(?:pattern2|\z)/s;
最后,如果您想要pattern1
和pattern2
之间的内容,可以使用
my ($following) = /pattern1((?:(?!pattern2).)*)pattern2/s;
有些人可能会推荐以下内容,但我讨厌使用?
量词修饰符。它太脆弱了。
my ($following) = /pattern1(.*?)pattern2/s;
答案 1 :(得分:3)
执行此操作的标准方法:
/pattern1(?s:(?!pattern2).)*\z/
答案 2 :(得分:1)
虽然ysth的答案涵盖了一般解决方案,但它需要一个匹配停止的显式模式。如果自然不存在这样的模式,我们可以改为使用匹配的字符串中包含的模式或字符串的结尾作为正向前瞻:
/pattern1.*?(?=pattern2|\z)/s;
匹配
"foo pattern1 pattern2 bar"
# |<------->|
其他解决办法不能。
答案 3 :(得分:0)
试试这个:
test.*?(?=notme|\z)
确保启用“m”(多行)和“s”(点匹配换行符)选项。
答案 4 :(得分:0)
基于负面预测的模式应该适合您:
(?s)pattern1(?!.*?pattern2).*$
(?s)
用于DOTALL,也可以使点匹配换行符。