什么perl正则表达式将正确匹配javascript关联数组?

时间:2015-10-06 00:28:48

标签: javascript json regex 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最终未被初始化。

4 个答案:

答案 0 :(得分:2)

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

                                                      ^^^^

问题是.默认情况下与\n不匹配。要么使用[\s\S],要么使用(?s) DOTALL标记。

参见演示。

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

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

答案 1 :(得分: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: $@" if $@;
    print "Match: "; dd $_;
}

将打印:

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

答案 2 :(得分: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

答案 3 :(得分:0)

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