'How can I convert from a{a{} b{}} to a[a[],b[]] using php preg_match?
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....
Solution 1:[1]
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;
}
Solution 2:[2]
I did a study in this way, but it was not enough. some array data is empty
<pre>
<?php
$data=[];
$number=[];
$temp=null;
$op=stream_context_create(array("ssl"=>array("verify_peer"=>false,"verify_peer_name"=>false)));
$f1=file_get_contents('https://huc.re/data.txt',false,$op);
$f2=preg_split('/\r|\n/si', $f1);
foreach($f2 as $k=>$f3){
$ilk_karakter = substr($f3 , 0 , 1);
if($ilk_karakter != "#"){
if(strstr($f3,"{")){
if($f3=="{"){
$last=$k-1;
$g=trim(str_replace("Group","",$f2[$last]));
$data[$g]=null;
}
}elseif(strstr($f3,"}")){
if($f3=="}"){
unset($last);
}
}else{
if(isset($last)){
$data[$g].=$f3.PHP_EOL;
}
}
}
}
//STEP 2
foreach($data as $k1=>$d1){
$ff2=preg_split('/\r|\n/si', $d1);
if(strstr($d1,"Group")){
$data[$k1]=[];
foreach($ff2 as $k=>$f3){
if(strstr($f3," Group") and !strstr($f3," Group")){
$last=$k;
if(isset($ff2[$last])){
$g=str_replace("%","",rawurlencode(utf8_decode(trim(str_replace("Group","",$ff2[$last])))));
if(trim($f3) != ""){
$data[$k1][$g]=null;
}
}
}else{
if(trim($f3) != ""){
$data[$k1][$g].=$f3.PHP_EOL;
}
}
}
}else{
$data[$k1]=[];
for($x=0;$x<count($ff2);$x++){
$a=explode(" ",$ff2[$x]);
if(count($a)>3){
if(trim($ff2[$x]) != ""){
$b=array_values(array_filter($a));
$data[$k1][$x]=$b;
}
}
}
$data[$k1]=array_values($data[$k1]);
}
}
//STEP 3
foreach($data as $k1=>$d1){
foreach($d1 as $k2=>$d2){
if(!is_array($d2)){
$ff2=preg_split('/\r|\n/si', $d2);
if(strstr($d2,"Group")){
$data[$k1][$k2]=[];
foreach($ff2 as $k=>$f3){
if(strstr($f3," Group") and !strstr($f3," Group")){
$last=$k;
if(isset($ff2[$last])){
$g=str_replace("%","",rawurlencode(utf8_decode(trim(str_replace("Group","",$ff2[$last])))));
if(trim($f3) != ""){
$data[$k1][$k2][$g]=null;
}
}
}else{
if(trim($f3) != ""){
if(isset($data[$k1][$k2][$g])){
$data[$k1][$k2][$g].=$f3.PHP_EOL;
}
}
}
}
}else{
$data[$k1][$k2]=[];
for($x=0;$x<count($ff2);$x++){
$a=explode(" ",$ff2[$x]);
if(count($a)>3){
if(trim($ff2[$x]) != ""){
$b=array_values(array_filter($a));
$data[$k1][$k2][$x]=$b;
}
}
}
$data[$k1][$k2]=array_values($data[$k1][$k2]);
}
}
}
}
print_r($data);
?>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Casimir et Hippolyte |
Solution 2 |