【问题标题】:Perl Regex vs Parsing [duplicate]Perl正则表达式与解析[重复]
【发布时间】:2014-10-28 13:58:09
【问题描述】:

所以我正在为特定类型的文件编写一个静态验证器。这些文件中应该有某个类似 JSON 的对象。下面的示例

theObject = {
key1 = value1,
key2 = value2,
key3 = {
    key4 = value4,
    key5 = value5
}
}

此文件中还有很多其他内容,但这是必需的,我需要验证它的存在和形式。我目前对此的解决方案是在对象名称之后找到第二个 } 并提取对象的内容,以便我可以将其粘贴到 JSON 解析器中。显然,如果创建者未能完全包含 key3,这将失败。

我一直在尝试调整正则表达式以适应表单

m/theObject = (\{.*\})/

显然这行不通。关于如何将相应的右括号与预期的左括号匹配的任何想法?

【问题讨论】:

    标签: regex json perl


    【解决方案1】:

    使用recursive regular expression 匹配平衡大括号。

    use strict;
    use warnings;
    
    use JSON;
    
    my $data = do { local $/; <DATA> };
    
    # Find theObject within your data:    
    if ( $data =~ m/^theObject\s*=\s*(\{ (?: (?> [^{}]+ ) | (?1) )* \})/msx ) {
        my $hashref = from_json($1);
    
        print "Perl Data Structure:\n";
        use Data::Dump;
        dd $hashref;
    
    } else {
        warn "Unable to find theObject";
    }
    
    __DATA__
    theObject = {
       "key2" : "value2",
       "key1" : "value1",
       "key3" : {
          "key5" : "value5",
          "key4" : "value4"
       }
    }
    

    输出:

    Perl Data Structure:
    {
      key1 => "value1",
      key2 => "value2",
      key3 => { key4 => "value4", key5 => "value5" },
    }
    

    【讨论】:

      【解决方案2】:

      看起来像嵌套大括号匹配的简单案例......在 Perl 中是通过递归正则表达式完成的。但在这种情况下,您也必须处理 JSON 字符串,因为它们可能包含 } 字符:

      (?(DEFINE)
          (?<json>
              \{ (?:
                  [^{}"']+
                  |(?<quote>["'])(?:[^\\"']+|\\.)*\k<quote>
                  |(?&json)
              )* \}
          )
      )
      
      theObject\s*=\s*(?&json)
      

      使用x 修饰符在模式中允许空格。

      演示:http://regex101.com/r/jX2rS6/1

      【讨论】:

        【解决方案3】:

        使用适当的解析器也是一种选择。到目前为止,我可以从您的示例中收集到类似

        Top       ::= KeyValue
        KeyValue  ::= Key '=' Value
        Key       ::= Name
        Value     ::= Name 
                    | Object
        Object    ::= '{' KeyValues '}'
        KeyValues ::= KeyValue+
        
        Name ~ [\w]+
        

        (如果我没有犯任何错误,这是Marpa::R2 的有效输入)。但是有很多我不知道的,比如你是否支持其他类型的值,可能是引用的字符串,空格规则是什么,“类 JSON”的东西到底是什么,以及 CPAN 上是否真的已经有一个解析器好够了:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-23
          • 2012-11-21
          • 2014-12-06
          • 1970-01-01
          • 1970-01-01
          • 2011-04-11
          • 1970-01-01
          • 2015-01-29
          相关资源
          最近更新 更多