REGEX PCRE 嵌套文本匹配的递归表达式
REGEX PCRE Recursive expression for nested text matching
所以我正在尝试做这样的事情(是的,包括换行符):
第 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
我希望得到一些指导
提前致谢
这是与您的示例匹配的模式:
^\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"
(带有 space))。 +
强制 \h
尽可能多地匹配,因此它必须消耗 space.
或者您可以将 \h*
拉入前瞻:(?!\h*(?:START|STOP)\h*$)
这也行得通,但是向前看会跳过任何 space 以查看它们后面是否有 START/STOP,只是让 [^\n]*
超出相同的 space 再次。以 \h*+
开头,我们匹配那些 space 一次,没有回溯。我想这是一个微优化。
所以我正在尝试做这样的事情(是的,包括换行符):
第 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
我希望得到一些指导
提前致谢
这是与您的示例匹配的模式:
^\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"
(带有 space))。 +
强制 \h
尽可能多地匹配,因此它必须消耗 space.
或者您可以将 \h*
拉入前瞻:(?!\h*(?:START|STOP)\h*$)
这也行得通,但是向前看会跳过任何 space 以查看它们后面是否有 START/STOP,只是让 [^\n]*
超出相同的 space 再次。以 \h*+
开头,我们匹配那些 space 一次,没有回溯。我想这是一个微优化。