除多字符标记外的任何正则表达式

Regex for anything but multicharacter token

我想创建一个正则表达式 returns 两个多字符标记之间的所有内容,其中开始标记为 ;;( 结束标记为 ;;),例如

;;(
  Capture this part, which can contain everything except the closing token 
;;)

我认为使用负前瞻的正则表达式 /;;\((?!;;\));;\)/ 应该可以工作,但是没有返回任何匹配项。是否可以为此使用正则表达式?

使用积极的后视和积极的前瞻。

(?<=;;\().*?(?=;;\))

演示:https://regex101.com/r/iK5wG4/2

为了匹配两个多字符定界符之间的某些文本,使用符合 unroll-the-loop 技术的正则表达式。

所以,我们有 ;;(;;) 个分隔符。

惰性点匹配正则表达式是;;\((.*?);;\)。这种模式效率不高,因为当输入的文本越来越大时,它会变得越来越慢。

;;\(([^;]*(?:;(?!;\))[^;]*)*);;\) 那样展开它会使匹配呈线性,如果块内有很多 ;,唯一的问题可能会出现在速度上。

timgeb 的解决方案需要 169 步才能完成匹配。我的只需要 16 步。

此外,展开的正则表达式不依赖于/s DOTALL修饰符,可以省略。

为什么不使用环视? 当您需要 重叠 匹配或有特定条件时,环视是很好的选择。在这种情况下,您需要 non-overlapping 匹配 ,因为 前导和尾随分隔符不相等 使用捕获组,在您需要获取的子模式周围使用一对未转义的括号。在 ;;\(([^;]*(?:;(?!;\))[^;]*)*);;\) 中,我们需要获取所有不是 ;;) 的文本,即 [^;]*(?:;(?!;\))[^;]*)* 部分。因此,我们用 ().

将其括起来

这个展开的部分匹配什么?

  • [^;]* - 除了 ;(尾随分隔符的第一个字符)
  • (?:;(?!;\))[^;]*)* - 零个或多个......
    • ;(?!;\)) - 尾随定界符的第一个字符,一个文字 ;,后面没有 ;)(尾随定界符的其余部分)
    • [^;]* - 除 ; 之外的零个或多个字符(尾随定界符的第一个字符)