Шаблоны регулярных выражений, вызывающие StackoverFlow - PullRequest
0 голосов
/ 15 ноября 2018

Я работаю над проектом в 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)

Я открыт для всех и всехсовет.Спасибо заранее.

1 Ответ

0 голосов
/ 17 ноября 2018

В итоге я использовал комбинацию обоих ответов от VGR и MatthewGreen. Re2j решил мою проблему с регулярными выражениями и увеличил производительность сопоставления.- в конечном итоге я решил меньше полагаться на регулярное выражение для этого и вместо этого использовать JSoup для синтаксического анализа и регулярное выражение для извлечения того, что я хотел из документа после удаления ненужных элементов.

...