如何防止.Net中的正则表达式挂起(或设置挂起的时间)

如何防止.Net中的正则表达式挂起(或设置挂起的时间),.net,regex,.net,Regex,我正在使用正则表达式删除html文件中的注释标记 (模式是:“您可以重写正则表达式,以便在不可能匹配时尽快失败,如下所示: <!--(?>(?:[^-]+|-(?!->))*)--> 这就是浏览器处理SGML注释的方式。事实上,如果没有匹配的-->,则在|\z)之后的所有内容 但我怀疑这并不是您真正想要的。为了获得更好的答案,我们需要知道您希望如何处理格式错误的HTML,如您发布的代码片段。正则表达式的性能问题很小。请不要这样做: (.|\s)* 量词是懒惰还是贪婪

我正在使用正则表达式删除html文件中的注释标记
(模式是:“
您可以重写正则表达式,以便在不可能匹配时尽快失败,如下所示:

<!--(?>(?:[^-]+|-(?!->))*)-->
这就是浏览器处理SGML注释的方式。事实上,如果没有匹配的
-->
,则在
|\z)之后的所有内容

但我怀疑这并不是您真正想要的。为了获得更好的答案,我们需要知道您希望如何处理格式错误的HTML,如您发布的代码片段。

正则表达式的性能问题很小。请不要这样做:

(.|\s)*
量词是懒惰还是贪婪完全不是重点。问题是,.and\s不是互斥的。空格可以由两个和\s匹配。因此,如果正则表达式遇到空格,它将首先将空格与匹配。如果正则表达式的其余部分失败,它将再次与\s匹配。如果有两个空格,它将首先将两者都与.,然后第一个与.,第二个与\s匹配,然后第一个与\s匹配,第二个与.,然后两者都与\s匹配。如您所见,您的正则表达式的复杂性为O(2^N)当它遇到一系列空格后跟某些正则表达式的剩余部分无法匹配的内容时。如果有10个空格,则有1024个置换。如果有32个空格,则有40亿个置换

您只在正则表达式失败时才看到问题的原因是,当正则表达式成功时,.s只匹配所有空格,而\s从未获得任何操作

我知道你想做什么:你想匹配一系列“任意”字符,包括换行符,这些字符通常不与点匹配。正确的解决方案是设置RegexOptions.SingleLine并使用此regex:

.*
如果无法设置RegexOptions.SingleLine,请使用此模式修改器执行相同操作:

(?s).*
如果无法使用该模式修饰符,例如,因为JavaScript不支持该修饰符,请使用具有两个互补缩写的字符类:

[\S\s]*
一旦你从你的正则表达式中得到了可怕的(.|\s)替换,它就会完美地工作。没有必要使用其他人建议的任何复杂正则表达式。一个懒惰的量词总是线性扩展。不相互排斥的替换总是杀死你的正则表达式。我确实称之为这个

如果您需要允许标记终止注释的正则表达式,请尝试以下操作:

(?s)<!--.*?(-->|</script>)
(?s)|)

(?s)|)
可能会导致没有
-->
的大型输入文本超时。对于这种情况,惰性匹配是一个糟糕的解决方案。请检查“展开循环”技术。但是,在特定上下文中,任何正则表达式都会失败。当此正则表达式遇到
时,使用s无法更有效地执行此操作如果在
之间真的允许任何事情,则使用单个正则表达式。展开循环适用于某些重复交替的正则表达式,但这里不是这样。对于正则表达式,我们不能太确定:请参阅vs.。至少20倍的效率。
(?s).*
[\S\s]*
(?s)<!--.*?(-->|</script>)