用于解析名称值对的正则表达式

时间:2008-10-03 18:17:11

标签: regex

有人可以提供正则表达式来解析字符串中的名称/值对吗?这些对用逗号分隔,值可以用引号括起来。例如:

AssemblyName=foo.dll,ClassName="SomeClass",Parameters="Some,Parameters"

3 个答案:

答案 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在创建此答案时非常有帮助。