2013-08-06 10 views
5

onestamente non so quale markup è questo (vorrei sapere se questo markup ha un nome). Qual è il modo più semplice per analizzare strutture come questa? ne ho molti nel file txt.Markup analogo al JSON

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 
} 
+0

Si potrebbe provare che esplode nelle schede, non molto efficiente, anche se :( –

+0

sembra che sia separato da tabulazioni/spazi, e le voci sono divise da ritorni a capo Se fosse solo numeri e stringhe senza spazi, sarebbe OK.Il problema sarà le stringhe con le virgolette, un po 'difficile da eguagliare con espressioni regolari .. – MightyPork

+9

perché la gente insiste a creare i propri formati di markup non standard quando esistono già tanti buoni standard ?? varrebbe la pena di sapere da dove proviene, dato che potrebbe esserci un parser perfettamente valido. Sembra molto simile al codice del programma, ma Non riconosco la lingua Sono davvero curioso di sapere da dove lo stai provando - come mai la gente che lo fornisce a te non può dirti di cosa si tratta? – Spudley

risposta

3

Qui è la mia soluzione:

Bisogna alimentare in essa solo l'interno dei tag {}, e si ottiene una matrice che rispetta le quotazioni stringa ecc

A differenza degli altri risposta, si prende cura di "text with quotes" e accetta entrambi gli spazi, le schede e mescolato per la formattazione.

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

uscita:.

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 
     ) 

) 
+0

sembra che la tua soluzione funzioni al meglio (nel caso in cui interrompi i commenti da solo), grazie! – Fedcomp

+0

È possibile verificare se il primo elemento di una matrice inizia con // e, in caso affermativo, ignorarlo. – MightyPork

+0

Ho avuto la funzione di pulizia/eliminazione dei commenti anche prima di porre questa domanda (e di aver reso la funzione dalla risposta). Comunque grazie! mi hai salvato il tempo. – Fedcomp

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

uscita:

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

) 

ruvida Spiegazione

  • Usa preg_match_all per trovare ogni blocco (unlockType someRandomText {....})
  • Loop attraverso ogni risultato di preg_match_all (ciascun blocco) per analizzare i blocchi singolarmente
    • Split il contenuto del {..} di nuove linee e quindi mappare ogni risultato a trim() per eliminare eventuali spazi iniziali e finali/linguette
      • Split ciascuna linea da 3 o più spazi (come schede corrette non sembrano essere stati utilizzati)
      • utilizzare il primo risultato della scissione come la chiave della nostra gamma, quindi spingere il resto della scissione nel valore
+0

Vorrei rendere il matcher 'unlockType' un analizzatore di token di dichiarazione di tipo agnostico, inoltre sostituire '\ t' con '\ s +' nel caso in cui. – Flosculus

+2

È bello che tu abbia risolto il problema, ma non vedo come questo aiuti molto la comunità. Dovresti considerare di spiegare quali strategie hai usato per risolvere questo e perché. –

+0

uh .. OK, sembra che la tua risposta sia sia più veloce che migliore. Beh, ci ho provato almeno ... – MightyPork