2014-09-03 142 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上是否已經有解析器好足夠:)