Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse JSON-like markup

Tags:

regex

php

honestly i don't know what markup is this (i would like to know if this markup have a name). What is easyest way to parse structures like this? i have a lot of them in txt file.

unlockType BirthdayCake {
       // Don't delete
    commonName      "Birthday Cake"
    autoTag
    category        Item
    path            models/
    timedExclusive  1
    descSymbol      BirthdayCakeDesc
    dispSymbol      BirthdayCakeDisp
    flairCfg        "Cake/Idle.aaf mat_BirthdayCake< /scale 1.5 /animation Cake/Idle.aaf 0 looping 0.8  /followDist 3.0 /moveSlew 0.0666  /moveVelThresh 10.0 /animEaseTime 1.0 /zOffRobot 2.7 /rotX 20.0 /zSpinDef bone_spinA 80.0"
    //OnInspectOrUnlock Menus previewInit Cake/Idle.aaf BirthdayCake< /scale 1.5 /animation Cake/Idle.aaf 0 looping 0.8 /rotSpeed 30 /pos 3.5 0 1 /scaleMult 1.0
    property        BirthdaySpirit          10
}
like image 731
Fedcomp Avatar asked Aug 06 '13 15:08

Fedcomp


1 Answers

$str = "unlockType BirthdayCake {
       // Don't delete
    commonName      \"Birthday Cake\"
    autoTag
    category        Item
    path            models/
    timedExclusive  1
    descSymbol      BirthdayCakeDesc
    dispSymbol      BirthdayCakeDisp
    flairCfg        \"Cake/Idle.aaf mat_BirthdayCake< /scale 1.5 /animation Cake/Idle.aaf 0 looping 0.8  /followDist 3.0 /moveSlew 0.0666  /moveVelThresh 10.0 /animEaseTime 1.0 /zOffRobot 2.7 /rotX 20.0 /zSpinDef bone_spinA 80.0\"
    //OnInspectOrUnlock Menus previewInit Cake/Idle.aaf BirthdayCake< /scale 1.5 /animation Cake/Idle.aaf 0 looping 0.8 /rotSpeed 30 /pos 3.5 0 1 /scaleMult 1.0
    property        BirthdaySpirit          10
}

unlockType PetFish3 {
        commonName              \"Lionfish\"
        autoTag
        category                Pet
        path                    flair/
        descSymbol              PetFish3Desc
        dispSymbol              PetFish3Disp
        flairCfg                \"pet flair/PetFishes/PetFish3.amf mat_PetFishes< /scale 1.1 /animation flair/PetFishes/idle3.aaf 0 looping 0.45 /moveAnim flair/PetFishes/fly1.aaf 1 looping 1.62  /followDist 3.0 /moveSlew 0.045 /moveVelThresh 8.0 /animEaseTime 0.45 /zOffRobot 2.6 /rotX 15.0 /moveSlew 0.05 /turnToMove 230\"
}
";

function parseThis($text)
{
    $types = array();
    preg_match_all('#(unlockType [^\{]+{.+?\n\s*})#s',$text,$matches);
    foreach($matches[1] as $str)
    {
        $typeName = preg_replace('#^[^ ]+ ([^ ]+).*#s','$1',$str);
        $contents = preg_split('#(\r?\n)+#',$str);
        $contents = array_map('trim',$contents);
        array_pop($contents);
        array_shift($contents);
        $data = array();
        foreach($contents as $line)
        {
            if(substr($line,0,2)=='//') continue;
            $parts = preg_split("#(\t+|\s{3,})#",$line);
            $title = array_shift($parts);
            $partC = count($parts);
            $data[$title] = $partC==1 ? $parts[0] : ($partC==0 ? '' : $parts);
        }
        $types[$typeName] = $data;
    }
    return $types;
}
$types = parseThis($str);
echo '<pre>'.print_r($types,true).'</pre>';

Output:

Array
(
    [BirthdayCake] => Array
        (
            [commonName] => "Birthday Cake"
            [autoTag] => 
            [category] => Item
            [path] => models/
            [timedExclusive] => 1
            [descSymbol] => BirthdayCakeDesc
            [dispSymbol] => BirthdayCakeDisp
            [flairCfg] => "Cake/Idle.aaf mat_BirthdayCake< /scale 1.5 /animation Cake/Idle.aaf 0 looping 0.8  /followDist 3.0 /moveSlew 0.0666  /moveVelThresh 10.0 /animEaseTime 1.0 /zOffRobot 2.7 /rotX 20.0 /zSpinDef bone_spinA 80.0"
            [property] => Array
                (
                    [0] => BirthdaySpirit
                    [1] => 10
                )

        )

    [PetFish3] => Array
        (
            [commonName] => "Lionfish"
            [autoTag] => 
            [category] => Pet
            [path] => flair/
            [descSymbol] => PetFish3Desc
            [dispSymbol] => PetFish3Disp
            [flairCfg] => "pet flair/PetFishes/PetFish3.amf mat_PetFishes< /scale 1.1 /animation flair/PetFishes/idle3.aaf 0 looping 0.45 /moveAnim flair/PetFishes/fly1.aaf 1 looping 1.62  /followDist 3.0 /moveSlew 0.045 /moveVelThresh 8.0 /animEaseTime 0.45 /zOffRobot 2.6 /rotX 15.0 /moveSlew 0.05 /turnToMove 230"
        )

)

Rough Explanation

  • Use preg_match_all to find each block (unlockType someRandomText { .... })
  • Loop through each result of preg_match_all (each block) to parse the blocks individually
    • Split the contents of the {..} by newlines and then map each result to trim() to remove any leading and trailing spaces/tabs
      • Split each line by 3 or more spaces (as proper tabs don't seem to have been used)
      • use the first result of the split as the key of our array, then push the rest of the split into the value
like image 51
MDEV Avatar answered Sep 29 '22 11:09

MDEV