5

老实说,我不知道这是什么标记(我想知道这个标记是否有名字)。解析这样的结构的最简单方法是什么?我在txt文件中有很多。

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
}
4

2 回答 2

5
$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>';

输出:

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"
        )

)

粗略的解释

  • 用于preg_match_all查找每个块(unlockType someRandomText { .... })
  • 循环遍历preg_match_all(每个块)的每个结果以单独解析块
    • 按换行符拆分内容,{..}然后将每个结果映射到trim()以删除任何前导和尾随空格/制表符
      • 将每一行拆分为 3 个或更多空格(因为似乎没有使用正确的制表符)
      • 使用拆分的第一个结果作为我们数组的键,然后将拆分的其余部分压入值
于 2013-08-06T15:55:39.197 回答
3

这是我的解决方案:

您必须仅将 {} 标记的内部提供给它,并且您会得到一个尊重字符串引号等的数组。

与其他答案不同,它处理"text with quotes"并接受空格、制表符和混合格式。

$a = <<<EOT
    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
EOT;

$lines = explode("\n", $a);

$parsed = array();

foreach($lines as $line) {
    $chars = str_split($line);

    $quoteOpen = false;

    $lastField = "";

    $lineFields = array();

    foreach($chars as $c) {
        if($c == '"') {
            if($quoteOpen) {
                $quoteOpen = false;
                $lineFields[] = $lastField;
            } else {
                $quoteOpen = true;
            }
            $lastField = "";
            continue;
        }

        if(preg_match("/\\s/", $c) === 0) {
            $lastField .= $c;
        } else {
            if($lastField != "" && !$quoteOpen) {
                $lineFields[] = $lastField;
                $lastField = "";
            } else {
                if(!$lastField == "") {
                    $lastField .= $c;
                }
            }
        }
    }

    if($lastField != "") {
        $lineFields[] = $lastField;
    }

    $parsed[] = $lineFields;
}

echo '<pre>'; print_r($parsed); echo '</pre>';

输出:

Array
(
    [0] => Array
        (
            [0] => commonName
            [1] => Birthday Cake
        )

    [1] => Array
        (
            [0] => autoTag
        )

    [2] => Array
        (
            [0] => category
            [1] => Item
        )

    [3] => Array
        (
            [0] => path
            [1] => models/
        )

    [4] => Array
        (
            [0] => timedExclusive
            [1] => 1
        )

    [5] => Array
        (
            [0] => descSymbol
            [1] => BirthdayCakeDesc
        )

    [6] => Array
        (
            [0] => dispSymbol
            [1] => BirthdayCakeDisp
        )

    [7] => Array
        (
            [0] => flairCfg
            [1] => 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
        )

    [8] => Array
        (
            [0] => //OnInspectOrUnlock
            [1] => Menus
            [2] => previewInit
            [3] => Cake/Idle.aaf
            [4] => BirthdayCake<
            [5] => /scale
            [6] => 1.5
            [7] => /animation
            [8] => Cake/Idle.aaf
            [9] => 0
            [10] => looping
            [11] => 0.8
            [12] => /rotSpeed
            [13] => 30
            [14] => /pos
            [15] => 3.5
            [16] => 0
            [17] => 1
            [18] => /scaleMult
            [19] => 1.0
        )

    [9] => Array
        (
            [0] => property
            [1] => BirthdaySpirit
            [2] => 10
        )

)
于 2013-08-06T16:03:38.060 回答