StackOverflowError с проверкой регулярного выражения Checkstyle 4.4

StackOverflow https://stackoverflow.com/questions/1800072

  •  05-07-2019
  •  | 
  •  

Вопрос

Здравствуйте,

Предыстория:

Я использую Checkstyle 4.4.2 с модулем проверки регулярных выражений, чтобы определить, когда имя файла в заголовках исходного кода java не совпадает с именем файла класса или интерфейса, в котором они находятся.Это может произойти, когда разработчик копирует заголовок из одного класса в другой и не изменяет тег "File:".

Использование регулярных выражений в программе проверки RexExp прошло через множество воплощений и (хотя на данный момент это, возможно, излишне) выглядит следующим образом:

File: (\w+)\.java\n(?:.*\n)*?(?:[\w|\s]*?(?: class | interface )\1)

Базовая форма файлов, которые я проверяю (хотя и значительно упрощенная), выглядит следующим образом

/*
 *
 *  Copyright 2009
 *  ...
 *  File: Bar.java
 *  ... 
 */
package foo
... 
import ..
...
/**
 * ...
 */
public class Bar
{...} 

Проблема:

Когда совпадение не найдено, (т.е.когда заголовок, содержащий "Файл:Bar.java " копируется в файл Bat.java ) Я получаю StackOverflowError для очень длинных файлов (мой тестовый пример составляет 1300 строк).

Я экспериментировал с несколькими визуальными тестерами регулярных выражений и могу видеть, что в несоответствующий случай когда механизм регулярных выражений передает строку, содержащую имя класса или интерфейса, он снова начинает поиск в следующей строке и выполняет некоторый откат, который, вероятно, вызывает StackOverflowError

Этот Вопрос:

Как предотвратить StackOverflowError, изменив регулярное выражение

Есть ли какой-нибудь способ изменить мое регулярное выражение таким образом, чтобы в несоответствующий случай (т.е.когда заголовок, содержащий "Файл:Bar.java " копируется в файл Bat.java ) что сопоставление прекратится, как только он проверит строку, содержащую имя интерфейса или класса, и увидит, что "\1" не соответствует первой группе.

В качестве альтернативы, если это можно сделать, возможно ли минимизировать поиск и сопоставление, которые выполняются после проверки строки, содержащей интерфейс или класс, таким образом минимизируя обработку и (надеюсь) ошибку StackOverflow?

Это было полезно?

Решение

Попробуй

File: (\w+)\.java\n.*^[\w \t]+(?:class|interface) \1

в режиме совпадения точек со всеми.Обоснование:

[\w\s] (| там не место) соответствует чему угодно, включая разрывы строк.Это приводит к большому количеству возвратов к строкам, которым соответствовала предыдущая часть регулярного выражения.

Если вы позволите жадной точке поглотить все до конца файла (быстро), а затем вернетесь назад, пока не найдете строку, начинающуюся со слов или пробелов / табуляции (но без перевода строк), а затем class или interface и \1, то для этого не требуется столько места в стеке.

Другим и, вероятно, даже лучшим решением было бы разделить проблему на части.

Первое совпадение с File: (\w+)\.java часть.Затем выполните второй поиск с помощью ^[\w \t]+(?:class|interface) плюс ко всему , \1 совпадение с первым поиском по одному и тому же файлу.

Другие советы

Последующие действия:

Я подключил приведенное выше предложение Тима Пьецчера, и его жадное решение действительно сработало быстрее и без StackOverflowError, когда совпадение не было найдено.Однако в положительном случае ошибка StackOverflowError все равно произошла.

Я взглянул на исходный код RegexpCheck.java.Шаблон classes создается в многострочном режиме таким образом, что выражения ^ и $ совпадают сразу после или непосредственно перед, соответственно, завершителем строки или концом входной последовательности.Затем он считывает весь файл класса в строку и выполняет рекурсивный поиск шаблона (см. findMatch()).Это, несомненно, является источником исключения StackOverflowException .

В конце концов, я не смог заставить это работать (и сдался) С тех пор, как Maven 2 выпустил maven-checkstyle-plugin-2.4 / Checkstyle 5.0 около 6 недель назад, мы решили обновить наши инструменты.Возможно, это не решит проблему StackOverflowError, но это даст мне еще кое-что для работы, пока кто-нибудь не решит, что нам нужно продолжить это снова.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top