[英]Regex pattern matching takes a long time for strings with length more than 30 chars
[英]Regex search with pattern containing (?:.|\s)*? takes increasingly long time
我的正则表达式要花越来越长的时间进行比赛(第5次大约30秒),但需要进行约500轮比赛。 我怀疑灾难性的回溯。 请帮忙! 如何优化此正则表达式:
String regex = "<tr bgcolor=\"ffffff\">\\s*?<td width=\"20%\"><b>((?:.|\\s)+?): *?</b></td>\\s*?<td width=\"80%\">((?:.|\\s)*?)(?=(?:</td>\\s*?</tr>\\s*?<tr bgcolor=\"ffffff\">)|(?:</td>\\s*?</tr>\\s*?</table>\\s*?<b>Tags</b>))";
编辑:由于目前尚不清楚(我不好):我正试图提取一个html格式的文档,并通过提取两个搜索组并在以后添加格式来重新格式化。
交替(?:.|\\\\s)+?
效率很高,因为它涉及太多的回溯。
基本上,此模式的所有变体都效率极低: (?:.|\\s)*?
, (?:.|\\n)*?
, (?:.|\\r\\n)*?
还有贪婪的对应对象( (?:.|\\s)*
, (?:.|\\n)*
, (?:.|\\r\\n)*
)。 (.|\\s)*?
可能是所有人中最糟糕的。
为什么?
两种选择.
和\\s
可能在同一位置匹配相同的文本,两者都至少匹配常规空格。 看到此演示程序需要3555个步骤才能完成, .*?
演示 (带有s
修饰符)需要1335个步骤才能完成。
像(?:.|\\n)*?
Java中的/ (?:.|\\n)*
通常会导致堆栈溢出问题 ,并且这里的主要问题与使用逐字符匹配char的交替(已经单独导致回溯)有关,然后修改了组与未知长度的量词。 尽管某些正则表达式引擎可以解决此问题并且不会引发错误,但是这种类型的模式仍然会导致速度变慢,并且不建议使用(仅在ElasticSearch Lucene正则表达式引擎中, (.|\\n)
是匹配任何字符的唯一方法) 。
解
如果要使用正则表达式匹配任何字符(包括空格),请使用
[\\s\\S]*?
或使用(?s)
(或Pattern.DOTALL
Matcher
选项)启用单行模式,仅使用即可.
(例如(?s)start(.*?)end
)。
注意 :要操作HTML,请使用专用的解析器,例如jsoup。 这是一篇讨论Java HTML解析器的文章 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.