Regex模式导致叠加流



我正在用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次。

我的问题是:有人看到这些模式会使用递归吗?或者任何可能表明模式本身就是导致溢出的原因的东西?

如果没有,也许我有一种方法可以将字符串缩小到不会导致过载的大小。

使用打印语句,似乎在尝试匹配模式时可能发生溢出:

"<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)

我愿意接受任何建议。提前谢谢。

我最终使用了VGR和MatthewGreen的两个答案的组合。Re2j解决了我的正则表达式问题,并提高了匹配的性能。-最终,我决定减少对regex的依赖,而是使用JSoup进行解析,并在删除不需要的元素后使用regex从文档中提取我想要的内容。

最新更新