我想创建一个正则表达式,它返回两个多字符标记之间的所有内容,其中开始标记为 ;;(
,结束标记为 ;;)
,例如
;;(
Capture this part, which can contain everything except the closing token
;;)
我认为使用负向先行的正则表达式 /;;\((?!;;\));;\)/
应该可以工作,但这不会返回任何匹配项。是否可以使用正则表达式来实现此目的?
最佳答案
为了匹配两个多字符分隔符之间的某些文本,需要使用符合展开循环技术的正则表达式。
因此,我们有 ;;(
和 ;;)
分隔符。
惰性点匹配正则表达式是 ;;\((.*?);;\)
。这种模式效率不高,因为当输入的文本越来越大时,它会变得越来越慢。
像;;\(([^;]*(?:;(?!;\))[^;]*)*);;\)
一样展开它使匹配呈线性,如果 block 内有许多 ;
,唯一的问题可能是速度。
timgeb 的解决方案需要 169 步才能完成匹配。我只需要 16 步。
此外,展开的正则表达式不依赖于 /s
DOTALL 修饰符,可以省略。
为什么不使用环视?当您需要重叠匹配或存在特定条件时,环视是很好的选择。在这种情况下,您需要非重叠匹配,因为前导和尾随分隔符不相等。 使用捕获组,即您需要获取的子模式周围的一对未转义括号。在 ;;\(([^;]*(?:;(?!;\))[^;]*)*);;\)
中,我们需要获取所有文本不是 ;;)
,即 [^;]*(?:;(?!;\))[^;]*)*
部分。因此,我们用 ()
将其括起来。
这个展开的部分匹配什么?
[^;]*
- 除了;
(尾随分隔符的第一个字符)之外的任何内容(?:;(?!;\))[^;]*)*
- 零个或多个序列...;(?!;\))
- 尾随分隔符的第一个字符,一个文字;
,后面不跟;)
(尾随分隔符的其余部分)[^;]*
-;
之外的零个或多个字符(尾随分隔符的第一个字符)
关于除多字符标记之外的任何内容的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34699452/