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
}
}
How can I convert the above structure to the following result.
$result=[
"test"=>[
"test1"=>[
0=>["#-#","Type","Val"],
1=>["1","typ1","10"],
2=>["1","typ1","10"],
3=>["1","typ1","10"]
],
"test2"=>[
0=>["#-#","Type","Val"],
1=>["1","typ1","10"],
2=>["1","typ1","10"]
]
]
];
I tried many patterns, but failed.
I tried with regex pattern and explode function. I Failed in Recursive function. I want to get the output as array or json. How can i do it.Thanks….
Advertisement
Answer
An approach in two steps: the first checks the whole string syntax with a recursive pattern, if this one is correct, then the second step parse the string with a recursive function.
$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;
}