代码之家  ›  专栏  ›  技术社区  ›  Chris Karcher

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

  •  19
  • Chris Karcher  · 技术社区  · 16 年前

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

    AssemblyName=foo.dll,ClassName="SomeClass",Parameters="Some,Parameters"
    
    3 回复  |  直到 16 年前
        1
  •  34
  •   Markus Jarderot    15 年前
    • /([^=,]*)=("[^"]*"|[^,"]*)/
      
    • 键和值的双引号转义:

      /((?:"[^"]*"|[^=,])*)=((?:"[^"]*"|[^=,])*)/
      
      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
  •  2
  •   Jonathan Leffler vy32    16 年前

    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美元是未定义的——准确地说。

        3
  •  0
  •   Brad Gilbert    16 年前

    如果你能使用,我会这样做 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 在创建这个答案时非常有帮助。