0

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

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

我认为接近的几个是:

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

或者

test.*(!notme)

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

任何帮助,将不胜感激。

4

5 回答 5

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;

最后,如果您想要介于pattern1and之间的内容pattern2,您可以使用

my ($following) = /pattern1((?:(?!pattern2).)*)pattern2/s;

有些人可能会推荐以下内容,但我讨厌使用?量词修饰符。它太脆弱了。

my ($following) = /pattern1(.*?)pattern2/s;
于 2013-06-21T21:23:14.663 回答
3

这样做的标准方法:

/pattern1(?s:(?!pattern2).)*\z/
于 2013-06-21T21:12:33.767 回答
1

虽然 ysth 的答案涵盖了一般解决方案,但它需要一个匹配停止的显式模式。如果自然不存在这样的模式,我们可以使用可能不包含在匹配字符串字符串末尾的模式作为正向预测:

/pattern1.*?(?=pattern2|\z)/s;

这匹配

"foo pattern1 pattern2 bar"
#   |<------->|

其他解决方案不能。

于 2013-06-21T21:27:44.037 回答
0

尝试这个:

test.*?(?=notme|\z)

确保启用“m”(多行)和“s”(点匹配换行符)选项。

于 2013-06-21T21:19:11.887 回答
0

基于负前瞻的模式应该适合您:

(?s)pattern1(?!.*?pattern2).*$

(?s)用于使点匹配换行符的 DOTALL。

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

于 2013-06-21T21:19:41.830 回答