Регулярное выражение для пар синтаксического анализа имени
Может ли кто-нибудь предоставить регулярное выражение для пар синтаксического анализа пар имя/значение из строки? Пара разделяется запятыми, и значение может быть добавлено в кавычки. Например:
AssemblyName=foo.dll,ClassName="SomeClass",Parameters="Some,Parameters"
Ответы
Ответ 1
-
Без выхода:
/([^=,]*)=("[^"]*"|[^,"]*)/
-
Двойной кавычек для обоих ключей и значений:
/((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/
key=value,"key with "" in it"="value with "" in it",key=value" "with" "spaces
-
Сбой обратной косой черты:
/([^=,]*)=("(?:\\.|[^"\\]+)*"|[^,"]*)/
key=value,key="value",key="val\"ue"
-
Полный сбой обратной косой черты:
/((?:\\.|[^=,]+)*)=("(?:\\.|[^"\\]+)*"|(?:\\.|[^,"\\]+)*)/
key=value,key="value",key="val\"ue",ke\,y=val\,ue
Изменить: Добавлены альтернативы экранирования.
Edit2: Добавлена другая альтернативная альтернатива.
Вам нужно будет очистить ключи/значения, удалив любые escape-символы и окружающие кавычки.
Ответ 2
Хороший ответ от MizardX. Незначительные ошибки - это не допускает пробелов вокруг имен и т.д. (Что может и не иметь значения), и оно собирает кавычки, а также цитированное значение (что также может не иметь значения), и у него нет механизма эвакуации для встраивания символы двойной кавычки в цитируемом значении (что еще раз может не иметь значения).
Как написано, шаблон работает с большинством расширенных систем регулярных выражений. Фиксация обморок, вероятно, потребует спуска, скажем, в Perl. Эта версия использует двойные кавычки для выхода - следовательно, a = "a" "b" генерирует значение поля "a" "b" (что не идеально, но может быть исправлено впоследствии достаточно легко):
/\s*([^=,\s]+)\s*=\s*(?:"((?:[^"]|"")*)"|([^,"]*))\s*,?/
Кроме того, вам нужно будет использовать $2 или $3 для сбора значения, тогда как с ответом MizardX вы просто используете $2. Таким образом, это не так просто или приятно, но оно охватывает несколько краевых случаев. Если более простой ответ достаточен, используйте его.
Тест script:
#!/bin/perl -w
use strict;
my $qr = qr/\s*([^=,\s]+)\s*=\s*(?:"((?:[^"]|"")*)"|([^,"]*))\s*,?/;
while (<>)
{
while (m/$qr/)
{
print "1= $1, 2 = $2, 3 = $3\n";
$_ =~ s/$qr//;
}
}
Это witters о том, что либо $2, либо $3 является undefined - точно.
Ответ 3
Вот как я мог бы это сделать, если вы можете использовать Perl 5.10
.
qr/
(?<key>
(?:
[^=,\\]
|
(?&escape)
)++ # Prevent null keys
)
\s*+
=
\s*+
(?<value>
(?"ed)
|
(?:
[^=,\s\\]
|
(?&escape)
)++ # Prevent null value ( use quotes for that )
)
(?(DEFINE)
(?<escape>\\.)
(?<quoted>
"
(?:
(?&escaped)
|
[^"\\]
)*+
"
)
)
/x
Элементы будут доступны через %+
.
perlretut
очень помог в создании этого ответа.