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

时间:2020-03-06 15:05:22  来源:igfitidea点击:

有人可以提供正则表达式来解析字符串中的名称/值对吗?两对之间用逗号分隔,并且值可以选择用引号引起来。例如:

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

解决方案

  • 无处可逃:
/([^=,]*)=("[^"]*"|[^,"]*)/
  • 键和值都使用双引号转义:
/((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/

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

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

编辑2:添加了另一个转义的替代方法。

我们将必须删除所有转义符和引号来清理键/值。

MizardX的回答很好。次要变量不允许在名称等之间留空格(这可能无关紧要),并且会收集引号和引用的值(也可能无关紧要),并且没有用于嵌入double的转义机制用引号引起来的字符(再次,可能无关紧要)。

如所写,该模式适用于大多数扩展的正则表达式系统。修复这些问题可能需要使用Perl。该版本使用双引号引起来-h 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= , 2 = , 3 = \n";
        $_ =~ s/$qr//;
    }
}

令人不安的是,准确地定义了$ 2或者$ 3.

如果我们可以使用Perl 5.10,这就是我会做的。

qr/
  (?<key>
    (?:
      [^=,\]
    |
      (?&escape)
    )++ # Prevent null keys
  )

  \s*+
  =
  \s*+

  (?<value>
    (?&quoted)
  |
    (?:
      [^=,\s\]
    |
      (?&escape)
    )++ # Prevent null value ( use quotes for that )
  )

  (?(DEFINE)
    (?<escape>\.)
    (?<quoted>
      "
        (?:
          (?&escaped)
        |
          [^"\]
        )*+
      "
    )
  )
/x

元素可以通过%+访问。

perlretut对创建此答案非常有帮助。