我试图理解正则表达式中的展开循环。两者之间的最大区别是什么:
MINISTÉRIO[\s\S]*?PÁG
和
MINISTÉRIO(?:[^P]*(?:P(?!ÁG\s:\s\d+\/\d+)[^P]*)(?:[\s\S]*?))PÁG
在这种情况下:
如果第一个做同样的事情,我为什么要使用第二个?
谢谢。
我试图理解正则表达式中的展开循环。两者之间的最大区别是什么:
MINISTÉRIO[\s\S]*?PÁG
和
MINISTÉRIO(?:[^P]*(?:P(?!ÁG\s:\s\d+\/\d+)[^P]*)(?:[\s\S]*?))PÁG
在这种情况下:
如果第一个做同样的事情,我为什么要使用第二个?
谢谢。
请参阅此展开循环技术源:
这种优化技巧用于优化表格的重复交替
(expr1|expr2|...)*
。这些表达式并不少见,在交替中使用另一个重复也可能导致超线性匹配。超线性匹配源于下限表达式(a*)*
。展开循环技术基于这样一个假设:在大多数情况下,您知道在重复的交替中,哪种情况应该是最常见的,而哪种情况是例外的。我们将第一个称为正常情况,第二个称为特殊情况。展开循环技术的一般语法可以写成:
正常*(特殊正常*)*
因此,这是一种优化技术,其中交替转换为线性匹配的原子。
这使得这些展开的模式非常有效,因为它们涉及较少的回溯。
你MINISTÉRIO[\s\S]*?PÁG
是一个非展开的模式,MINISTÉRIO[^P]*(?:P(?!ÁG)[^P]*)*PÁG
而是。请参阅演示(均与 PCRE 选项一起保存以显示上面框中的步骤数。正则表达式性能因正则表达式引擎而异,但这会准确告诉您性能差异)。在 之后添加更多文本text
:第一个正则表达式将开始需要更多步骤才能完成,第二个将仅在添加后显示更多步骤P
。因此,在已知部分中使用的字符不常见的文本中,展开模式非常有效。
请参阅我的答案中的,和量词之间.*?
.*
[^"]*+
的差异部分,以了解延迟匹配的工作原理(您[\s\S]*?
的方法.*?
与允许 a.
匹配换行符的语言中的 DOTALL 修饰符相同)。
惰性匹配模式总是缓慢且低效吗?并非总是如此。对于非常短的字符串,惰性点匹配通常更好(1-10 个符号)。当我们谈论长输入时,可以有前导分隔符,没有尾随分隔符,这可能会导致过度回溯,从而导致超时问题。
当您有可能很长的任意输入并且可能没有匹配时,请使用展开模式。
当你的输入被控制时使用惰性匹配,你知道总会有一个匹配,一些已知的设置日志格式,等等。
常规字符串文字 ( "String\u0020:\"text\""
):"[^"\\]*(?:\\.[^"\\]*)*"
多行注释正则表达式 ( /* Comments */
):/\*[^*]*\*+(?:[^/*][^*]*\*+)*/
@<...>@
评论正则表达式: @<[^>]*(?:>[^@]*)*@