我有一些我需要用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 :(得分: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
或
答案 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*
。