用于parsing名称值对的正则expression式

有人可以提供正则expression式来parsingstring中的名称/值对吗? 这些对由逗号分隔,并且值可以可选地用引号括起来。 例如:

AssemblyName=foo.dll,ClassName="SomeClass",Parameters="Some,Parameters" 
  • 无处可逃:

     /([^=,]*)=("[^"]*"|[^,"]*)/ 
  • 双引号转义键和值:

     /((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/ key=value,"key with "" in it"="value with "" in it",key=value" "with" "spaces 
  • 反斜杠string转义:

     /([^=,]*)=("(?:\\.|[^"\\]+)*"|[^,"]*)/ key=value,key="value",key="val\"ue" 
  • 完整的反斜杠转义:

     /((?:\\.|[^=,]+)*)=("(?:\\.|[^"\\]+)*"|(?:\\.|[^,"\\]+)*)/ key=value,key="value",key="val\"ue",ke\,y=val\,ue 

编辑:添加了转义的替代品。

编辑2:增加了另一个逃避的select。

您将不得不通过删除任何转义字符和周围的引号来清除键/值。

从MizardX很好的答案。 小数点 – 它不允许名称周围的空格等(这可能无关紧要),它收集引号以及引用的值(这也可能不重要),并且没有用于embedded的转义机制所引用的值中的双引号字符(这又可能不重要)。

正如所写,该模式适用于大多数扩展的正则expression式系统。 解决这个问题可能需要下降到Perl。 这个版本使用加倍的引号来逃避 – 因此a =“a”“b”产生一个字段值“a”“b”(这并不完美,但是可以很容易地修复):

 /\s*([^=,\s]+)\s*=\s*(?:"((?:[^"]|"")*)"|([^,"]*))\s*,?/ 

此外,你必须使用$ 2或$ 3来收集价值,而与MizardX的答案,你只需使用$ 2。 所以,它不是那么容易或很好,但它涵盖了一些边缘情况。 如果简单的答案是足够的,使用它。

testing脚本:

 #!/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这个问题来说是一种威胁 – 准确地说。

如果你可以使用Perl 5.10这是我的方法。

 QR /
   (?<键>
     (?:
       [^ =,\\]
     |
       (?&逃逸)
     )++#防止空键
   )

   \ S * +
   =
   \ S * +

   (?<值>
     (?&引)
   |
     (?:
       [^ =,\ S \\]
     |
       (?&逃逸)
     )++#防止空值(使用引号)
   )

   (?(DEFINE)
     (?<逃逸> \\。)
     (?<引述>
       “
         (?:
           (?&转义)
         |
           [^“\\]
         )* +
       “
     )
   )
 /X

元素将通过%+访问。

perlretut在创build这个答案时非常有帮助。