(pattern1)任何东西的正则表达式(!pattern2)

时间:2013-06-21 21:09:43

标签: regex perl

我正在尝试创建一个执行以下操作的正则表达式:

匹配( pattern1 )后跟任何包括新行的内容,只要它不包含( pattern2

我认为很接近的几个是:

test[\s\S]+(!notme)

test.*(!notme)

我最终在perl做这个,但我正在这个网站上测试: http://www.myregextester.com/index.php

任何帮助都将不胜感激。

5 个答案:

答案 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;

最后,如果您想要pattern1pattern2之间的内容,可以使用

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,也可以使点匹配换行符。

现场演示:http://www.rubular.com/r/pgEOOr1RpF