use strict;
my $str = '{"menu": {
"header": "SVG Viewer",
"items": [
{"id": "Open"},
{"id": "OpenNew", "label": "Open New"},
null,
{"id": "ZoomIn", "label": "Zoom In"},
{"id": "ZoomOut", "label": "Zoom Out"},
{"id": "OriginalView", "label": "Original View"},
null,
{"id": "Quality"},
{"id": "Pause"},
{"id": "Mute"},
null,
{"id": "Find", "label": "Find..."},
{"id": "FindAgain", "label": "Find Again"},
{"id": "Copy"},
{"id": "CopyAgain", "label": "Copy Again"},
{"id": "CopySVG", "label": "Copy SVG"},
{"id": "ViewSVG", "label": "View SVG"},
{"id": "ViewSource", "label": "View Source"},
{"id": "SaveAs", "label": "Save As"},
null,
{"id": "Help"},
{"id": "About", "label": "About Adobe CVG Viewer..."}
],
"test": [
"Some value",
4,
null,{}
],
"empty_array":[-0.34E+4]
}}';
my $regex = qr/(?(DEFINE)
(?<quote>['"])
(?<pair>
(?>
\w+
|(?:
(?<pairQuote>(?"e))[^'"]+?\k<pairQuote>
)
)
\s*\:
)
(?<string>
(?<stringQuote>(?"e))[\S\s]*?(?<!\\)\k<stringQuote>
)
(?<integer>\-?\d+(?:\.\d+)?(?:e[-+]\d+)?)
(?<scalar>true|false|null|(?&integer))
(?<elements>
\s*(?&value)
(?(R&array)|(?>(?:\s*\,(?&elements))|\s*))
)
(?<array>\[(?>(?&elements)|\s*)\])
(?<value>
(?&object)
|(?&string)
|(?&scalar)
|(?&array)
)
(?<members>
\s*(?&pair)\s*(?&value)
(?(R&object)|(?>(?:\s*\,(?&members))|\s*))
)
(?<object>\{(?&members)?\})
)
\A(?&object)\Z/imxp;
if ( $str =~ /$regex/g ) {
print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
# print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
# print "Capture Group 2 is $2 ... and so on\n";
}
# ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
# Named capture groups can be called via $+{name}
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Perl, please visit: http://perldoc.perl.org/perlre.html