2015-10-06 79 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" }