繁体   English   中英

使用Java / Javascript的正则表达式/正则表达式:性能下降或无限循环

[英]Regular expression/Regex with Java/Javascript: performance drop or infinite loop

我想在这里提交一个我想要了解的非常具体的性能问题。

目标

我正在尝试用正则表达式验证自定义合成器。 通常,我没有遇到性能问题,所以我喜欢使用它。

案件

正则表达式:

^(\{[^\][{}(),]+\}\s*(\[\s*(\[([^\][{}(),]+\s*(\(\s*([^\][{}(),]+\,?\s*)+\))?\,?\s*)+\]\s*){1,2}\]\s*)*)+$

一个有效的synthax:

{Section}[[actor1, actor2(syno1, syno2)][expr1,expr2]][[actor3,actor4(syno3, syno4)][expr3,expr4]]

你可以在这里找到正则表达式和测试文本: https//regexr.com/3jama

我希望足够了,我不知道如何解释我想要比正则表达式更匹配的东西;-)。

问题

将正则表达式应用于有效文本并不需要花费太多,它几乎是即时的。 但是当涉及到特定的无效文本案例时,regexr应用程序会挂起。 它不是特定于regexr应用程序,因为我也遇到了我自己的java代码或javascript代码的戏剧性表现。

因此,我的需求是验证用户正在键入文本。 我甚至可以想象在点击时验证文本,但是如果用户提交的文本结构如下所示,或者另一个产生相同性能下降,则我无法承担该应用程序的挂起。

再现问题

只需从测试文本中删除尾随的“]”字符即可

因此,提高性能下降的无效文本变为:

{Section}[[actor1, actor2(syno1, syno2)][expr1,expr2]][[actor3,actor4(syno3, syno4)][expr3,expr4

另一个无效测试可能是,并且没有性能下降:

{Section}[[actor1, actor2(syno1, syno2)][expr1,expr2]][[actor3,actor4(syno3, syno4)][expr3,expr4]]]

请求

如果一个正则表达的大师能够解释我做错了什么,或者为什么我的用例不适合正则表达式,我会很高兴的。

这个答案适用于您评论中的精简正则表达式:

^(\{[^\][{}(),]+\}(\[(\[([^\][{}(),]+(\(([^\][{}(),]+\,?)+\))?\,?)+\]){1,2}\])*)+$

您的原始模式的问题类似。

你正面临着灾难性的回溯。 每当正则表达式引擎无法完成匹配时,它就会回溯到字符串中,试图找到将模式与某些子字符串匹配的其他方法。 如果你有很多模糊的模式,特别是如果它们出现在重复内部,测试所有可能的变化需要花费很多时间。 请参阅链接以获得更好的解释。

您使用的子模式之一是以下(为了更好的可视化而采用多行模式):

([^\][{}(),]+
  (\(
    ([^\][{}(),]+\,?)+
  \))?
\,?)+

这应该匹配像actor4(syno3, syno4)这样的字符串。 将这种模式稍微缩小,你得到([^\\][{}(),]+,?)+ 如果删除了,? 从它,你得到([^\\][{}(),]+)+这是一个营养回溯的开门,因为字符串可以用这种模式以很多不同的方式匹配。

我得到你试图用这个模式做的事情 - 匹配一个标识符 - 以及用逗号分隔的其他其他标识符。 然而,正确的方法是: ([^\\][{}(),]+(?:,[^\\][{}(),]+)*) 现在没有一种模糊的方式可以回溯到这种模式。

为上面显示的整个模式执行此操作(是的,还有另一个可选的逗号,必须推出)并将其插回到您的完整模式我得到:

^(\{[^\][{}(),]+\}(\[(\[([^\][{}(),]+(\(([^\][{}(),]+(?:,[^\][{}(),]+)*)\))?(?:\,[^\][{}(),]+(\(([^\][{}(),]+(?:,[^\][{}(),]+))*\))?)*)\]){1,2}\])*)+$

不走回头路灾难性

您可能希望自己帮忙并将其拆分为子模式,这些子模式可以使用实际源中的字符串连接在一起,或者如果使用PCRE模式则使用定义。

请注意,一些正则表达式引擎允许使用原子组和占有量词,进一步帮助避免不必要的回溯。 由于您在标题中使用了不同的语言,因此您必须自行检查,哪一种可用于您选择的语言。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM