sha*_*uec 5 regex reluctant-quantifiers
我有一个正则表达式:
(<select([^>]*>))(.*?)(</select\s*>)
Run Code Online (Sandbox Code Playgroud)
由于它使用延迟重复量词,对于更长的字符串(选项超过500),它回溯超过100,000次并失败.请帮我找一个更好的正则表达式,不使用懒惰重复量词
<select[^>]*>[^<]*(?:<(?!/select>)[^<]*)*</select>
Run Code Online (Sandbox Code Playgroud)
...或以人类可读的形式:
<select[^>]*> # start tag
[^<]* # anything except opening bracket
(?: # if you find an open bracket
<(?!/select>) # match it if it's not part of end tag
[^<]* # consume any more non-brackets
)* # repeat as needed
</select> # end tag
Run Code Online (Sandbox Code Playgroud)
这是弗里德尔在他的书“掌握正则表达式”中开发的“展开循环”技术的一个示例。我使用基于不情愿量词的模式在 RegexBuddy 中进行了快速测试:
(?s)<select[^>]*>.*?</select>
Run Code Online (Sandbox Code Playgroud)
...大约需要 6,000 步才能找到匹配项。展开的循环模式仅需要 500 步。当我从结束标记 ( </select) 中删除右括号时,使匹配变得不可能,只需要 800 步就报告失败。
如果您的正则表达式风格支持所有格量词,也可以继续使用它们:
<select[^>]*+>[^<]*+(?:<(?!/select>)[^<]*+)*+</select>
Run Code Online (Sandbox Code Playgroud)
实现匹配所需的步骤数大致相同,但在此过程中使用的内存要少得多。如果不可能匹配,它会更快失败;在我的测试中,大约需要 500 步,与找到匹配项所需的步数相同。