регулярное выражение генерирует ошибку StackOverFlow - PullRequest
0 голосов
/ 19 сентября 2010

У меня простой вопрос регулярного выражения.У меня есть следующая многострочная строка:

description: line1\r\nline2\r\n...

И я пытаюсь найти все строки, которые идут после description:.Я использовал следующее регулярное выражение (и еще несколько):

description: ((.*\r\n){1,})

... безуспешно.Затем я обнаружил, что в Sun есть ошибка 'Regexp StackOverflow' (заявлена ​​как не исправленная), см. Ошибка # 5050507 .Кто-нибудь может предоставить мне волшебную формулу, чтобы преодолеть эту досадную ошибку?Обратите внимание, что общая длина строк должна превышать 818 байт !!

Ответы [ 2 ]

1 голос
/ 20 сентября 2010

Поскольку вы сопоставляете что-либо, кроме текста description, вы можете просто разрешить точке совпадать с новыми строками Pattern.DOTALL:

description:\s(.*)

Итак, в Java:

Pattern regex = Pattern.compile("description:\\s(.*)", Pattern.DOTALL);
Matcher regexMatcher = regex.matcher(subjectString);
if (regexMatcher.find()) {
    ResultString = regexMatcher.group(1);
}

Единственное семантическое отличие вашего регулярного выражения (не считая того факта, что оно не унесет ваш стек), заключается в том, что оно также будет соответствовать, если то, что следует после description:, не будет содержать символ новой строки. Кроме того, ваше регулярное выражение не будет соответствовать последней строке файла, если оно не заканчивается новой строкой, моя будет. Какое поведение предпочтительнее - ваше решение.

Конечно, ваша функциональность может эмулироваться следующим образом:

description:\s(.*\r\n)

но я сомневаюсь, что это действительно то, что вы хотите. Или это?

0 голосов
/ 19 сентября 2010

Я могу воспроизвести ошибку:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; ++i)
{
    sb.append("j\r\n");
}
String s = "description: " + sb.toString(); 
Pattern pattern = Pattern.compile("description: ((.*\r\n){1,})");
//Pattern pattern = Pattern.compile("description: ((?:.*\r\n)++)");

Matcher matcher = pattern.matcher(s);
boolean b = matcher.find();
if (b) {
    System.out.println(matcher.group(1));
}

Квантор {1,} совпадает с +, поэтому вместо него следует использовать +, но это все равно не работает. Чтобы исправить это, вы можете (как указывает Бат К.) изменить + на ++, сделав его притяжательным, что отключает возврат, предотвращая переполнение стека.

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