有人可以提供正则表达式来解析字符串中的名称/值对吗?这些对用逗号分隔,值可以用引号括起来。例如:
AssemblyName=foo.dll,ClassName="SomeClass",Parameters="Some,Parameters"
答案 0 :(得分:35)
无法逃脱:
/([^=,]*)=("[^"]*"|[^,"]*)/
键和值的双引号转义符:
/((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/
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:添加了另一个转义替代方案。
您必须通过删除任何转义字符和周围的引号来清理键/值。
答案 1 :(得分:2)
MizardX的答案很好。轻微的小问题 - 它不允许名称周围的空格等(这可能无关紧要),它收集引号和引用的值(也可能无关紧要),并且它没有嵌入的转义机制引用值中的双引号字符(再次,可能无关紧要)。
如上所述,该模式适用于大多数扩展正则表达式系统。修复这些琐事可能需要下降到比如说Perl。这个版本使用双引号来转义 - 因此a =“a”“b”生成一个字段值'a“”b'(这不是完美的,但之后可以很容易地修复):
/\s*([^=,\s]+)\s*=\s*(?:"((?:[^"]|"")*)"|([^,"]*))\s*,?/
此外,您必须使用$ 2或$ 3来收集值,而使用MizardX的答案,您只需使用$ 2。所以,它不是那么容易或不好,但它涵盖了一些边缘情况。如果答案更简单,请使用它。
测试脚本:
#!/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//;
}
}
这大概是$ 2或$ 3未定义 - 准确。
答案 2 :(得分:0)
如果您可以使用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
在创建此答案时非常有帮助。