2015-10-06 83 views
1

我有一些JavaScript代码,我需要用Perl来分析:perl正则表达式将正确匹配javascript关联数组?

var materials ={ 
    foo: "bar", 
    bar: "baz", 
    baz: "foo" 
}, 

我有此Javascript变量作为字符串,我想匹配的关联数组的身体,这样我可以解析它作为使用parse_json()的Perl的JSON。我想不通,我用我的正则表达式做错了什么:

my ($json_str) = $js_code =~ m/var\smaterials\s=\s+({.+}),/i;

$json_str最终被初始化。

+0

你可能只是看它不同。现在你正试图匹配字符串的json部分。修复你的正则表达式将是微不足道的(允许'\ s *'而不需要'\ s +')。但是,JSON可能比这个例子更复杂。放弃你不想要的部分可能会更容易:'s/^ [^ {] + //'。这将剥夺第一个“{”之前的所有内容。 – DavidO

+2

你究竟想要做什么? 'JSON.stringify(材料)'会给你真正的JSON开始,这使得一切都变得更加容易。 –

回答

1

使用如预期还存在多个元素的排除组像[^}]+作品:

#!/usr/bin/env perl 

my $js_code = <<'__END__'; 
var previousOne = { 
    pFoo: "pBar", 
    pBar: "pBaz", 
    pBaz: "pFoo" 
}, 
var materials ={ 
    foo: "bar", 
    bar: "baz", 
    baz: "foo" 
}, 
var anotherOne = { 
    aFoo: "aBar", 
    aBar: "aBaz", 
    aBaz: "aFoo" 
} 
__END__ 

my ($json_str) = $js_code =~ m/\s*var\s+materials\s*=\s*({[^}]+}),?/; 
print "json_str = ${json_str}\n"; 

我放松了一些空白的约束。您可以测试它和在线编辑here

+0

为什么downvote?这是一个真正的问题。我已经测试过了(每个人都可以在答案中执行perl脚本...) –

+0

谢谢你指出我正确的方向:我已经用贪婪的*所有格*折叠了默认的贪婪行为,行为(如''[\ s \ S] ++''),根本不会回溯。我已经删除了错误的假设,但让代码导致它起作用。 –

0

等号和花括号之间没有空格,但花样至少需要一个。删除\s+或将其更改为\s*

+0

这不提供问题的答案。要批评或要求作者澄清,请在其帖子下方留言。 –

+2

@WesFoster这不是一个答案吗?这是一个试图解决这个问题,只要我能说出正确的一个。你能在这里详细说明你的推理吗? – Anders

2
my ($json_str) = $js_code =~ m/var\smaterials\s=\s*({[\s\S]+?}),/i; 

                 ^^^^ 

问题是.不通过default.So匹配\n要么使用[\s\S]或使用(?s)DOTALL标志。

查看演示。

https://regex101.com/r/cJ6zQ3/7

https://regex101.com/r/cJ6zQ3/8

+0

为什么''[\ s \ S] +''不匹配''}}'''也是? (以及所有其他的直到字符串的末尾)它不需要惰性修饰符'''?'''来工作吗?像这样''[\ s \ S] +?'' –

+1

@GsusRecovery这与你的答案是一样的问题。你的假设是错的。它会匹配'}'但是它会回溯,因为re必须匹配'}' ['s'''''''''''''''''''''匹配到最后一个'}' – vks

2

如果你可以给JSON对象的键(如下面的例子),你可以尝试JSON::Decode::Regexp,该模块包括一个正则表达式,你可以用它来匹配JSON。作为奖励,您将JSON对象加载为Perl哈希。示例代码:

use Data::Dump; 
use JSON::Decode::Regexp; 

my $json_code = <<'_'; 
var materials ={ 
    "foo": "bar", 
    "bar": "baz", 
    "baz": "foo" 
}, 
_ 

if ($json_code =~ /(\{.+)/s) { 
    local $_ = $1; 
    local $^R; 
    eval { /\A$JSON::Decode::Regexp::FROM_JSON/ } or die "No match"; 
    die "No match: [email protected]" if [email protected]; 
    print "Match: "; dd $_; 
} 

会打印:

Match: { bar => "baz", baz => "foo", foo => "bar" }