Соответствие регулярному выражению не заканчивается

2

Я когда-то ответил на вопрос о соответствии строки с кавычками.

Кажется, что есть случаи, которые зависают на .NET и сбой на Mono (с OutOfMemoryException), например:

var reg = new Regex(@"^""([^\\""]*(\\"")*(\\[^""])*)*""");
reg.Match("\"                               ");

Два вопроса:

1) почему это происходит?

2) как улучшить это регулярное выражение? Я хочу, чтобы он сохранил все "функции".

  • 2
    Это, вероятно, случай катастрофического возврата . Вопрос, который вы связали, имеет лучший ответ.
  • 0
    К вашему сведению, ваше выражение работает для меня, используя движок Javascript Regex: rexfiddle.net/slfowcR
Показать ещё 3 комментария
Теги:
mono

1 ответ

0
Лучший ответ

Это действительно (cf Tim S.) катастрофическое возвращение с этой частью вашего шаблона: (\\[^""])*)*, который позволяет все, что возможно в мире, и заставить двигатель регулярных выражений попробовать слишком много возможностей. (Лучшие иллюстрации можно найти, если вы следуете ссылке Тима С.)

Другой шаблон для этого:

var reg = new Regex(@"(?s)""(?>[^\\""]+|\\{2}|\\.)*""");

(Идея состоит в том, чтобы сопоставить все четное число обратных косых черт (вторая часть чередования), прежде чем разрешить реальным экранированным символам (третья часть чередования).)

  • 0
    Я не думаю, что в моем регулярном выражении есть что-то о четном числе обратных косых черт, просто нужно поймать все между неэкранированными кавычками. Это немного чрезмерно, чтобы быть уверенным. Поскольку Тим С. предоставил только комментарий, я просто приму ваш ответ, который также является правильным :) Спасибо
  • 0
    @PiotrZierhoffer: обратите внимание, что вы должны добавить захватывающие скобки, чтобы извлечь нужный контент (или использовать пару lookbehind / lookahead для заключения двойных кавычек). О четном количестве обратных слэшей рассмотрим строку, подобную этой: abc "def" "g\"hi" "jkl\\" "mn\\\"o" . Результат должен быть: def , g"hi , jkl\`, mn \ "o`.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню