Полный ответ ниже оптимизирует производительность регулярных выражений, но для предотвращения переполнения стека, в качестве простого решения, просто сделайте повторяющуюся группу притяжательным .
Не притяжательные повторяющиеся группы с необходимостью выборарекурсивные вызовы, чтобы разрешить возврат.Устранение этой проблемы решает проблему, поэтому просто добавьте +
после *
:
"(?m)\"\"\"(?:[^\"]|(?:\"[^\"])|(?:\"\"[^\"]))*+\"\"\""
Также обратите внимание, что если вы хотите сопоставить весь ввод, вынужно позвонить matches()
, а не lookingAt()
.
Повышение производительности
Примечание: быстрый тест производительности показал, что это будет более чем в 6 раз быстрее , чем регулярное выражение в ответе по x4rf41 .
Вместо совпадения с одним из
- Не цитата:
[^\"]
- Ровно одна цитата:
(?:\"[^\"])
- Ровно две цитаты:
(?:\"\"[^\"])
inцикл, сначала сопоставьте все до цитаты.Если это одинарная или двойная кавычка, но не тройная, сопоставьте 1-2 кавычки, затем все до следующей кавычки, при необходимости повторите.Наконец, сопоставьте окончательную тройную кавычку.
Это сопоставление является окончательным, поэтому сделайте повторы притяжательными.Это также предотвращает переполнение стека в случае, если на входе есть много встроенных кавычек.
"{3} match 3 leading quotes
[^"]*+ match as many non-quotes as possible (if any) {possesive}
(?: start optional repeating group
"{1,2} match 1-2 quotes
[^"]++ match one or more non-quotes (at least one) {possesive}
)*+ end optional repeating group {possesive}
"{3} match 3 trailing quotes
Поскольку вы не используете ^
или $
, нет необходимости в (?m)
( MULTILINE )
в виде строки Java:
"\"{3}[^\"]*+(?:\"{1,2}[^\"]++)*+\"{3}"