Регулярное выражение для C# дословно как строки (обработка ""-подобных escape-выражений)

Я пытаюсь извлечь информацию из rc-файлов. В этих файлах "-чары в строках экранируются путем удвоения их (""), аналогично дословным строкам C#. Есть ли способ извлечь строку?

Например, если у меня есть следующая строка "this is" "test" "", я бы хотел получить это "" test "". Это также должно быть нежадным (очень важно).

Я пытался использовать следующее регулярное выражение;

"(?<text>[^""]*(""(.|""|[^"])*)*)"

Однако выступление было ужасным. Я основал это на объяснении здесь: http://ad.hominem.org/log/2005/05/quoted_strings.php

Кто-нибудь есть идея справиться с этим с помощью регулярного выражения?

5 ответов

Решение

У вас есть несколько вложенных квантификаторов повторения. Это может иметь катастрофические последствия для производительности.

Попробуйте что-то вроде этого:

(?<=")(?:[^"]|"")*(?=")

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

Это также заставляет вас захватывать что-либо. Желаемым результатом будет просто полная строка, которую вы хотите (без внешних кавычек).

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

Это оказывается намного проще, чем вы ожидаете. Строковый литерал с экранированными кавычками выглядит в точности как набор простых строковых литералов, работающих вместе:

"Some ""escaped"" quotes"

"Some " + "escaped" + " quotes"

Так что это все, что вам нужно, чтобы соответствовать:

(?:"[^"]*")+

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

Попробуй это (?<=^")(.*?"{2}.*?"{2})(?="$)это будет возможно быстрее, чем два предыдущих и без ошибок.

Не, если это лучше или хуже, чем у m.buettner (не догадываясь - он, кажется, знает свое дело), ​​но я подумал, что выкину это для критики.

"(([^"]+(""[^"]+"")*)*)"
  • Подходим "начало строки
  • Несколько раз соответствуют не "или два"
  • Подходим "конец строки"

"([^"]|(""))*?"

Другие вопросы по тегам