2011-10-06 45 views
1

我有一个看起来像这样的字符串。这显然是一个多行字符串,我想将它分成每个字符串一个字符串。如何从多行字符串中提取多个模式

{ 
    "timestamp":1317911700, 
    "application":"system.dev", 
    "metrics":{ 
     "qlen":0, 
     "read.bytes":0, 
     "write.bytes":185165., 
     "busy":0.021423 
    }, 
    "dimensions":{ 
     "device":"sda" 
    } 
} 

{ 
    "timestamp":1317911700, 
    "application":"system.fs", 
    "metrics":{ 
     "inodes.used":246627, 
     "inodes.free":28703901, 
     "capacity.kb":227927024, 
     "available.kb":209528472, 
     "used.kb":6820512 
    }, 
    "dimensions":{ 
     "filesystem":"/" 
    } 
} 

{ 
    "status_code":0, 
    "application":"system", 
    "status_msg":"Data collected successfully" 
} 

我正则表达式是这样的:

/^({\n[^}]+^})/m 

但我只捕捉:

{ 
    "status_code":0, 
    "application":"system", 
    "status_msg":"Data collected successfully" 
} 

这还挺有道理的,因为这是其中第一个大括号。我试图做的是从任何地方捕捉/^{/到任何有/ ^} /的位置作为单个字符串。但我认为其中的其他花括号是tr

+0

有没有你不能使用一个真正的JSON解析器来提取你想要的数据的原因是什么? – AFresh1

+0

这不是有效的JSON。它必须看起来像是有效的。 [{stanza1},{stanza2},{stanza99}]。我已经通过一个验证器来运行它,它现在是失败的。我不控制输出,所以我需要捕捉它并自己咀嚼。我想知道我是否能用前瞻来做点什么。我的@foo =/somelookahead /; – gdanko

+0

没关系,我看到每个节末尾都没有逗号,所以JSON解析不起作用。 – AFresh1

回答

4

我能想到一些方法。

  • 有关于如何实现一个递归模式某处perlre一个例子。这很难。你需要考虑字符串中的curlies。

  • Text::Balanced已经提供了匹配平衡包袱(包括卷发)的方法。这可能更容易,因为我认为它可以考虑字符串中的curlies。

  • 它看起来像你可以简单地分割空白行。

    @json_snippets = split /^$/m, $json_snippets; 
    
  • 但最可靠的解决方案是使用JSON::XS的‘增量解析器’。 (搜索,它的文档)。

+0

完美!增量式解析器有窍门!谢谢! – gdanko

0

如果您不能使用JSON解析器来正确地执行此操作,那么我只会在节的末尾进行分割。

my @stanzas = split /^}\K\n\n/; 
+1

这不是有效的JSON。这更像是一系列JSON片段。 – ikegami

1
for my $stanza (split /^$/m, $str) { 
    ... 
} 
+0

然后你有有效的JSON字符串: foreach my $ stanza(split(/^$/m,$ str)){$ json = decode_json($ stanza); print Dumper($ json); } – Kenny

相关问题