Нахождение заключенных в кавычки строк с завершенными кавычками в C# с помощью регулярного выражения

Я пытаюсь найти весь заключенный в кавычки текст на одной строке.

Пример:

"Some Text"
"Some more Text"
"Even more text about \"this text\""

Я должен добраться:

  • "Some Text"
  • "Some more Text"
  • "Even more text about \"this text\""

\"[^\"\r]*\" дает мне все за исключением последнего, из-за завершенных кавычек.

Я читал о \"[^\"\\]*(?:\\.[^\"\\]*)*\" при работе, но я получаю ошибку во время выполнения:

parsing ""[^"\]*(?:\.[^"\]*)*"" - Unterminated [] set.

Как я фиксирую это?

40
задан Alan Moore 27 November 2013 в 07:21
поделиться

6 ответов

То, что у вас есть, есть пример методики «развернутого цикла» Friedl, но у вас есть некоторая путаница о том, как выразить его как строку литерала. Вот как следует посмотреть на компилятор Regex:

"[^"\\]*(?:\\.[^"\\]*)*"

Начальный «[^« \\] * соответствует цитату, а затем ноль или более любых символов, отличных от кавычек или обратных челков. Эта часть одна, наряду с финалом «, будет соответствовать простую цитируемую строку без встроенных эвакуационных последовательностей, таких как « Это » или » .

Если он делает , сталкивается с обратной ячейкой, \\. потребляет обратную косание и то, что следует, и [^ "\\] * (опять же) до следующей обратной черта или цитата. Эта часть повторяется столько раз, сколько необходимо до тех пор, пока не возникает необоснованная цитата (или не достигает конца строки, и попытка совпадения не удается).

Обратите внимание, что это будет соответствовать «Foo \» - в \ "Foo \" - «Бар» . Это, возможно, по-видимому, выставляют недостаток в Regex, но это не так; Это вход , который недействителен. Цель состояла в том, чтобы соответствовать цитированным строкам, необязательно, содержащей сбежавшие сбежавшие котировки, встроенные в другой текст - почему бы там были сбежаны котировки снаружи цитируемых строк? Если вам действительно нужно поддерживать это, у вас есть гораздо более сложная проблема, требуя совершенно другого подхода.

Как я уже сказал, вышеизложенное является то, как регельс должен смотреть на компилятор Regex. Но вы пишете в виде строкового литерала, и те, кто склонны относиться к определенным персонажам специально - то есть, обратные косания и кавычки. К счастью, C # 'S Verbatim Strings сэкономит вам хлопот, чтобы дважды избежать обратных стяков; Вам просто нужно избежать каждой цитаты с помощью другой цитаты:

Regex r = new Regex(@"""[^""\\]*(?:\\.[^""\\]*)*""");

, поэтому правило - двойное кавычки для компилятора C # и двойной задней ячейки для компилятора Regeex - приятно и легко. Это конкретное регельс может выглядеть немного неловко, с тремя кавычками на одном конце, но считают альтернативу:

Regex r = new Regex("\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"");

в Java, вы всегда должны писать их таким образом. : - (

79
ответ дан 27 November 2019 в 01:17
поделиться

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

-121--818390-
"(\\"|\\\\|[^"\\])*"

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

В C #:

StringCollection resultList = new StringCollection();
Regex regexObj = new Regex(@"""(\\""|\\\\|[^""\\])*""");
Match matchResult = regexObj.Match(subjectString);
while (matchResult.Success) {
    resultList.Add(matchResult.Value);
    matchResult = matchResult.NextMatch();
} 

Редактирование: добавлена ​​сбежавшая обратная косание к списку для правильной обработки «Это тест \\» .

Объяснение:

Сначала соответствует символу цитаты.

Затем альтернативы оцениваются слева направо. Двигатель сначала пытается сопоставить сбежавшую цитату. Если это не совпадает, он пытается сбежать обратной косой черты. Таким образом, он может различать «Hello \» String, продолжается « и и и « Строка заканчивается здесь \\ ».

Если либо не совпадают, то что-то еще разрешено За исключением цитаты или символа обратной косочета. Затем повторите.

Наконец, сопоставить закрывающую цитату.

4
ответ дан 27 November 2019 в 01:17
поделиться

Я знаю, что это не самый чистый метод, но с вашим примером я бы проверил символ перед », чтобы увидеть, если это \ . Если это так, я бы проигнорировал цитату.

1
ответ дан 27 November 2019 в 01:17
поделиться

Любой шанс вам нужно сделать: \ "[^ \" \\\\\] * (?: \\. [^ \ "\\\\] *) * \"

0
ответ дан 27 November 2019 в 01:17
поделиться

Я рекомендую получить RegexBuddy . Это позволяет вам играть с ним, пока не убедитесь, что все в вашем тестовом наборе.

Что касается вашей проблемы, я бы попробую четыре / вместо двух:

\"[^\"\\\\]*(?:\\.[^\"\\\\]*)*\"
3
ответ дан 27 November 2019 в 01:17
поделиться

Регулярное выражение

(?<!\\)".*?(?<!\\)"

также обрабатывает текст, который начинается с сбежавшей цитаты:

\"Some Text\" Some Text "Some Text", and "Some more Text" an""d "Even more text about \"this text\""
2
ответ дан 27 November 2019 в 01:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: