2014-09-03 93 views
0

所以我正在为特定类型的文件写一个静态验证器。这些文件预计会有一个类似JSON的对象。下面Perl正则表达式vs解析

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

样品有很多在这个文件中其他的东西,但这是必需的,我需要验证它的存在和形式。我目前的解决方案是在object的名字后面找到2nd,并提取出对象的内容,以便我可以将它放在JSON解析器中。很显然,如果创作者未能完全包含key3,则会失败。

我一直在试图调整正则表达式,以适应形式

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

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

回答

0

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

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

theObject\s*=\s*(?&json) 

使用x修改,以允许在空白的格局。

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

0

使用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" }, 
} 
0

使用合适解析器始终是一个选择了。到目前为止,我可以从你的例子搜集是一样的东西

Top  ::= KeyValue 
KeyValue ::= Key '=' Value 
Key  ::= Name 
Value  ::= Name 
      | Object 
Object ::= '{' KeyValues '}' 
KeyValues ::= KeyValue+ 

Name ~ [\w]+ 

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