<?php
$str = <<<'STR'
Group test
{
Group test1
{
#-# Type Val
1 typ1 10
2 typ2 10
3 typ3 10
}
Group test2
{
#-# Type Val
1 typ1 10
2 typ2 10
}
}
STR;
$pattern = <<<'REGEX'
~
(?(DEFINE)
(?<group>
Group \s+ \g<groupName> \s* { \s*
(?:
\g<group> (?: \s+ \g<group>)*
|
\g<line> (?: \h*+ \s+ \g<line> )*
)?
\s*
}
)
(?<groupName> \w+ )
(?<line> \g<value> (?: \h+ \g<value>)* )
(?<value> [^\s{}]+ )
)
\A \s* \g<group> \s* \z (*:MAIN_GROUP)
~x
REGEX;
function group2array($group) {
$ret = [];
$index = 0;
// this pattern extracts the group name and the group content
preg_match(
'~Group \s+ (?<name> \w+ ) \s* { \s* (?<content> .* \S ) \s* } ~sx',
$group, $match
);
$name = $match['name'];
$content = $match['content'];
$ret[$name] = [];
preg_match_all( // this one extracts groups or lines of values
'~
\s* (?<group> Group \s+ \w+ \s* { [^{}]*+ (?: \g<group> [^{}]* )*+ } )
|
\s* (?<line> [^\s{}]+ (?: \h+ [^\s{}]+ )* )
~x',
$content, $matches, PREG_SET_ORDER
);
foreach($matches as $m) {
if (isset($m['line'])) {
$ret[$name][$index++] = preg_split('~\s+~', $m['line']);
} else {
$group = group2array($m['group']);
$ret[$name][key($group)] = current($group);
}
}
return $ret;
}
if ( preg_match($pattern, $str) ) { // check the string syntax before parsing
$result = group2array($str);
echo json_encode($result), PHP_EOL,
print_r($result, true), PHP_EOL;
}
- Output for 7.4.0 - 7.4.33, 8.0.1 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.6
- {"test":{"test1":[["#-#","Type","Val"],["1","typ1","10"],["2","typ2","10"],["3","typ3","10"]],"test2":[["#-#","Type","Val"],["1","typ1","10"],["2","typ2","10"]]}}
Array
(
[test] => Array
(
[test1] => Array
(
[0] => Array
(
[0] => #-#
[1] => Type
[2] => Val
)
[1] => Array
(
[0] => 1
[1] => typ1
[2] => 10
)
[2] => Array
(
[0] => 2
[1] => typ2
[2] => 10
)
[3] => Array
(
[0] => 3
[1] => typ3
[2] => 10
)
)
[test2] => Array
(
[0] => Array
(
[0] => #-#
[1] => Type
[2] => Val
)
[1] => Array
(
[0] => 1
[1] => typ1
[2] => 10
)
[2] => Array
(
[0] => 2
[1] => typ2
[2] => 10
)
)
)
)
preferences:
144.28 ms | 406 KiB | 121 Q