Regex для сопоставления строковых литералов С#

Я пытаюсь написать регулярное выражение, которое будет соответствовать строке, содержащей пары имя-значение формы:

<name> = <value>, <name> = <value>, ...

Где < значение > - строковый литерал С#. Я уже знаю, что мне нужно найти через это регулярное выражение. Пока у меня есть следующее:

regex = new Regex(fieldName + @"\s*=\s*""(.*?)""");

Это хорошо работает, но он, конечно, не подходит для случая, когда строка, которую я пытаюсь сопоставить, имеет значение < значение > с экранированной цитатой. Я изо всех сил пытаюсь решить, как это решить, я думаю, мне нужен взгляд, но нужно несколько указателей. В качестве примера я хотел бы иметь возможность сопоставить значение "трудного" именованного значения ниже:

difficult = "\\\a\b\'\"\0\f \t\v", easy = "one"

Я был бы признателен за достойное объяснение с вашими ответами, я хочу учиться, а не копировать; -)

Ответы

Ответ 1

Попробуйте это, чтобы захватить ключ и значение:

(\w+)\s*=\s*(@"(?:[^"]|"")*"|"(?:\\.|[^\\"])*")

В качестве бонуса он также работает по стенографическим строкам.
Пример: http://regexhero.net/tester/?id=9f38ec0d-8f53-4e03-aa58-520fcf4c0f98
Примеры С#: http://ideone.com/b7YWn, http://ideone.com/Ykbci p >

Здесь аннотированная версия:

string pattern = @"
(\w+)\s*=\s*    # key =
(               # Capturing group for the string
    @""               # verbatim string - match literal at-sign and a quote
    (?:
        [^""]|""""    # match a non-quote character, or two quotes
    )*                # zero times or more
    ""                #literal quote
|               #OR - regular string
    ""              # string literal - opening quote
    (?:
        \\.         # match an escaped character,
        |[^\\""]    # or a character that isn't a quote or a backslash
    )*              # a few times
    ""              # string literal - closing quote
)";
MatchCollection matches = Regex.Matches(s, pattern, 
                                        RegexOptions.IgnorePatternWhitespace);

Обратите внимание, что регулярная строка позволяет экранировать все символы, в отличие от С#, и позволяет использовать символы новой строки. Это должно быть легко исправить, если вам нужна проверка, но это должен быть файл для синтаксического анализа.

Ответ 2

Это должно соответствовать только строковой литеральной части (вы можете использовать все, что хотите для начала и конца):

Regex regex = new Regex("\"((\\.)|[^\\\\\"])*\"");

и если вам нужен шаблон, который не допускает "многострочные" строковые литералы (как литераторы на С#):

Regex regex = new Regex("\"((\\[^\n\r])|[^\\\\\"\n\r])*\"");

Ответ 3

Вы можете использовать это:

@"  \s* = \s* (?<!\\)""  (.* ) (?<!\\)"""

Он почти как ваш, но вместо использования "" я использовал (?<!\\)"" для соответствия, когда суффикс\отсутствует, поэтому он не будет соответствовать экранированным кавычкам.