java - 导致 StackoverFlow 的正则表达式模式
问题描述
我正在使用 JAVA8 开发一个项目,我想从目录或链接中获取 HTML 文件,并从文件中删除所有样式和脚本标签并返回剩下的内容。这是在大量文件上迭代执行的。
现在,这是我用来删除指定标签的两种不同的正则表达式模式。
//remove style tags and style tag content
update = update.replaceAll("<style\\b[^<]*(?:(?!</style>)<[^<]*)*</style>", "");
//remove script tags and script tag content
update = update.replaceAll("<script[\\s\\S]*?>[\\s\\S]*?</script>", "");
这工作了一段时间,但似乎偶尔我会遇到一个java.lang.StackOverflowError
.
我相信当文件太大时会发生这种情况。我做了一些研究,发现如果你"|"
在你的模式中使用,这可能会发生,因为这个运算符使用递归,这可能是内存密集型的,具体取决于遍历的级别。
我已经设法在不同的测试文件上反复使用这些模式多达 1000 次。
我的问题是:有没有人看到这些模式会使用递归?或任何暗示模式本身是导致溢出的原因?
如果没有,也许我有办法将字符串减小到不会导致这种过载的大小。
使用 print 语句似乎在尝试匹配模式时可能发生溢出:
"<script[\\s\\S]*?>[\\s\\S]*?</script>"
此外,有人告诉我我可以改用这个:
"<script[\\s\\S]+?>[\\s\\S]+?</script>"
因为这并没有向前看。此模式在 Regexr 中有效,但在 JAVA 应用程序中实现后不会提供相同的输出。
这是我收到的堆栈跟踪:
Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$Curly.match0(Pattern.java:4252)
at java.util.regex.Pattern$Curly.match(Pattern.java:4236)
at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3800)
at java.util.regex.Pattern$Neg.match(Pattern.java:5099)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
at java.util.regex.Pattern$Loop.match(Pattern.java:4787)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
at java.util.regex.Pattern$Curly.match0(Pattern.java:4274)
我愿意接受任何建议。提前谢谢你。
解决方案
推荐阅读
- mysql - 如何从终端执行sql文件?
- mysql - SQL 查询。加入但在一个表中,每个元组有 2 次出现的连接属性
- ruby-on-rails - 更改分页器的 Kaminari url
- php - Laravel 队列数据未从构造函数传递到处理程序
- c# - 使用依赖注入测试 TypeFilterAttribute
- google-sheets - 如何使用 COUNTIF 定义多个工作表的范围?
- object - Vue V:模型动态创建对象
- javascript - 如何在 JavaScript 中创建一系列可以单击以执行相同功能的不同版本的按钮?
- android - 如果 API < 26,如何实现 android.support.v4.widget.TextViewCompat 以自动调整文本大小
- mysql - MySQL搜索字段但删除所有非数字字符