所以我想尝试做这样的事情(是的,包括新行):
匹配#1
START
START
stuff
STOP
more stuff
STOP
匹配#2
START
START
stuff
STOP
more stuff
STOP
这是我走了多远
START(.*?^(?:(?!STOP).)*$|(?R))|STOP
参数" g" " M" " I"和" s"
问题是在STOP
与最后一次" STOP"匹配后,我无法匹配任何内容。在整篇文章中。
这是一个regex101示例
https://regex101.com/r/vD4nX6/1
我会赞美一些指导
提前致谢
答案 0 :(得分:3)
这是一个与您的示例匹配的模式:
^\h*START\h*\n(?:\h*+(?!(?:START|STOP)\h*$)[^\n]*\n|(?R)\n)*\h*STOP\h*$
使用/mg
标记(住在https://regex101.com/r/iK9tK5/1)。
背后的想法:
^ # beginning of line
\h* START \h* \n # "START" optionally surrounded by horizontal whitespace
# on a line of its own
(?: # between START/STOP, every line is either "normal"
# or a recursive START/STOP block
\h*+ # a normal line starts with optional horizontal whitespace
(?! # ... not followed by ...
(?: START | STOP ) \h* $ # "START" or "STOP" on their own
)
[^\n]* \n # any characters, then a newline
|
(?R) \n # otherwise it's a recursive START/STOP block
)* # we can have as many items as we want between START/STOP
\h* STOP \h* # "STOP" optionally surrounded by horizontal whitespace
$ # end of line
我已经\h*+
占有所有权,以避免意外地将" STOP"
与\h*
的0次迭代进行匹配,而不是"STOP"
(他们是'然后是" STOP"
(带空格))。 +
强制\h
尽可能多地匹配,因此必须占用空间。
或者,您可以将\h*
拉入前瞻:(?!\h*(?:START|STOP)\h*$)
这也可行,但随后前瞻将跳过任何空格以查看它们是否后跟START / STOP,只是让[^\n]*
外面再次查看相同的空格。在\h*+
开头,我们匹配这些空格一次,没有回溯。我想这是微观优化。