Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模式包含(?:.|\s)*的正则表达式搜索?需要越来越长的时间_Java_Regex - Fatal编程技术网

Java 模式包含(?:.|\s)*的正则表达式搜索?需要越来越长的时间

Java 模式包含(?:.|\s)*的正则表达式搜索?需要越来越长的时间,java,regex,Java,Regex,我的正则表达式需要越来越长的时间来匹配(第五次约30秒),但需要进行大约500轮的匹配。 我怀疑是灾难性的回溯。 请帮忙!如何优化此正则表达式: String regex = "<tr bgcolor=\"ffffff\">\\s*?<td width=\"20%\"><b>((?:.|\\s)+?): *?</b></td>\\s*?<td width=\"80%\">((?:.|\\s)*?)(?=(?:</td&

我的正则表达式需要越来越长的时间来匹配(第五次约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>))";
String regex=“\\s*?((?:.| \\s)++):*?\\s*((?:.| \\s)*?)(?=(?:\\s*?\\s*))|(?:\\s*?\\s*?\\s*?标记));
编辑:因为不清楚(我的错):我正试图获取一个html格式的文档,并通过提取两个搜索组并在之后添加格式化来重新格式化。

交替
(?:.|\\s)+?
非常低效,因为它涉及太多回溯

基本上,这种模式的所有变体都是非常低效的:
(?:.|\s)*?
(?:.|\n)*?
(?:.|\r\n)*?
(?:.|\s)*
(?:.|\n)*
(?:。\r\n)*
<代码>(.|\s)*?可能是其中最糟糕的

为什么?

两个备选方案,
\s
可以在同一位置匹配同一文本,两者至少匹配规则空格。请参见完成3555个步骤和完成1335个步骤

Java中的
(?:.|\n)*?
/
(?:.|\n)*
等模式通常会导致错误,这里的主要问题是使用交替(已经单独导致回溯)逐字符匹配,然后使用未知长度的量词修改组。尽管某些正则表达式引擎可以处理此问题,并且不会抛出错误,但这种类型的模式仍然会导致速度减慢,因此不建议使用(仅在ElasticSearch Lucene正则表达式引擎中,
(.|\n)
是匹配任何字符的唯一方法)

解决方案

如果要将任何字符(包括空格)与正则表达式匹配,请使用

[\\s\\S]*?
或者使用
(?s)
(或
模式.DOTALL
匹配器
选项)启用单线模式,只需使用
(例如
(?s)开始(.*)结束


注意:要操作HTML,请使用专用解析器,如jsoup。下面是一篇讨论SO的帖子。

通常的答案是:不要在HTML或XML上使用regexp…@Bruce然后你将如何解决这种问题?你有
(?:。|\\s)+?
,这是非常低效的。将其更改为
+?
并使用
模式.DOTALL
(或模式开头的
(?s)
)要好得多(或者如果您不想使用DOTALL标志,只需使用
[\\s]+?
)。但是使用jsoup或其他基于HTML解析器的解决方案是最好的。@Stribizev谢谢,我会检查它是否足够快,或者我是否会更改我的解决方案。事实上,有70K行需要匹配。在Java中,始终使用内联标志使点匹配任何字符。它的开销比字符类小solution@DeVeXD3VeX:实际上,这在所有情况下都是正确的:使用内置结构/类型/类可以获得最佳性能。因此,
(?s)
匹配任何包含换行符的字符都是可取的。@Stribizev再次感谢!你真的加快了我的正则表达式的速度,从每次比赛5分钟的时间成指数增加到5秒左右