2013-10-24 68 views
0

我需要解析看起來像JSON文件的文件,但它不是。它錯過了: char,因此我無法使用json_decode解析它。我不是這個文件的所有者,所以我必須像它一樣。我如何解析這個文件?有什麼想法嗎?謝謝PHP如何使用不合適的json格式解析文件

"sound_materials" 
{ 
    "common" 
    { 
     "value"  "0" 
     "start_drag_sound"  "ui.inv_pickup" 
     "end_drag_sound"  "ui.inv_drop" 
     "equip_sound"  "ui.inv_equip" 
    } 
    "chest" 
    { 
     "value"  "1" 
     "start_drag_sound"  "ui.inv_pickup_chest" 
     "end_drag_sound"  "ui.inv_drop_chest" 
    } 
    "pennant" 
    { 
     "value"  "2" 
     "start_drag_sound"  "ui.inv_pickup_pennant" 
     "end_drag_sound"  "ui.inv_drop_pennant" 
    } 
    "key" 
    { 
     "value"  "3" 
     "start_drag_sound"  "ui.inv_pickup_key" 
     "end_drag_sound"  "ui.inv_drop_key" 
    } 
    "metal_small" 
    { 
     "value"  "4" 
     "start_drag_sound"  "ui.inv_pickup_metalsmall" 
     "end_drag_sound"  "ui.inv_drop_metalsmall" 
     "equip_sound"  "ui.inv_equip_metalsmall" 
    } 
    "metal_armor" 
    { 
     "value"  "5" 
     "start_drag_sound"  "ui.inv_pickup_metalarmour" 
     "end_drag_sound"  "ui.inv_drop_metalarmour" 
     "equip_sound"  "ui.inv_equip_metalarmour" 
    } 
    "metal_blade" 
    { 
     "value"  "6" 
     "start_drag_sound"  "ui.inv_pickup_metalblade" 
     "end_drag_sound"  "ui.inv_drop_metalblade" 
     "equip_sound"  "ui.inv_equip_metalblade" 
    } 
    "metal_heavy" 
    { 
     "value"  "7" 
     "start_drag_sound"  "ui.inv_pickup_metalheavy" 
     "end_drag_sound"  "ui.inv_drop_metalheavy" 
     "equip_sound"  "ui.inv_equip_metalheavy" 
    } 
    "staff_or_blunt" 
    { 
     "value"  "8" 
     "start_drag_sound"  "ui.inv_pickup_staff" 
     "end_drag_sound"  "ui.inv_drop_staff" 
     "equip_sound"  "ui.inv_equip_staff" 
    } 
    "robes" 
    { 
     "value"  "9" 
     "start_drag_sound"  "ui.inv_pickup_robes" 
     "end_drag_sound"  "ui.inv_drop_robes" 
     "equip_sound"  "ui.inv_equip_robes" 
    } 
    "leather" 
    { 
     "value"  "10" 
     "start_drag_sound"  "ui.inv_pickup_leather" 
     "end_drag_sound"  "ui.inv_drop_leather" 
     "equip_sound"  "ui.inv_equip_leather" 
    } 
    "quiver" 
    { 
     "value"  "11" 
     "start_drag_sound"  "ui.inv_pickup_quiver" 
     "end_drag_sound"  "ui.inv_drop_quiver" 
     "equip_sound"  "ui.inv_equip_quiver" 
    } 
    "stone" 
    { 
     "value"  "12" 
     "start_drag_sound"  "ui.inv_pickup_stone" 
     "end_drag_sound"  "ui.inv_drop_stone" 
     "equip_sound"  "ui.inv_equip_stone" 
    } 
    "wood" 
    { 
     "value"  "13" 
     "start_drag_sound"  "ui.inv_pickup_wood" 
     "end_drag_sound"  "ui.inv_drop_wood" 
     "equip_sound"  "ui.inv_equip_wood" 
    } 
    "bone" 
    { 
     "value"  "14" 
     "start_drag_sound"  "ui.inv_pickup_bone" 
     "end_drag_sound"  "ui.inv_drop_bone" 
     "equip_sound"  "ui.inv_equip_bone" 
    } 
    "jug" 
    { 
     "value"  "15" 
     "start_drag_sound"  "ui.inv_pickup_jug" 
     "end_drag_sound"  "ui.inv_drop_jug" 
     "equip_sound"  "ui.inv_equip_jug" 
    } 
    "gun" 
    { 
     "value"  "16" 
     "start_drag_sound"  "ui.inv_pickup_gun" 
     "end_drag_sound"  "ui.inv_drop_gun" 
     "equip_sound"  "ui.inv_equip_gun" 
    } 
    "highvalue" 
    { 
     "value"  "17" 
     "start_drag_sound"  "ui.inv_pickup_highvalue" 
     "end_drag_sound"  "ui.inv_drop_highvalue" 
     "equip_sound"  "ui.inv_equip_highvalue" 
    } 
} 

編輯:

所以我用H2O suggered正則表達式,它的偉大工程,以格式化文件。我的錯誤是,在上面的例子中,我只把一個部分用1行鍵。

我有一些人,你有子鍵,在這種情況下,我應該需要添加[]分隔符的子項文件的一部分..:

+0

以及它不是json ...它是在一個數組?或一個字符串?或笏? –

+0

你必須做一些重字符串解析。見http://stackoverflow.com/questions/13236819/how-to-fix-badly-formatted-json-in-php – subZero

+0

如何正則表達式?您可以執行搜索並替換爲帶有引號內的兩個字符串的行,用空格分隔,並用冒號替換空格。 –

回答

4

這絕對afwul 什麼 - 這格式,是 - 因爲它不是 - json

$json = preg_replace('/^(\s*"[^"]+")/m', '$1:', $json); 

DEMO

正則表達式屍檢:如果你能保證它總是看起來酷似你的OP(每行一個鍵),那麼你可以這樣做修復它

  • ^ - 該行必須從這裏開始
  • (\s*"[^"]+") - 捕獲組(這就是$1是)匹配:
    • \s* - 空間/標籤/換行符重複0次或多次
    • " - 字面"字符
    • [^"]+ - 任何字符不"重複1或多次
    • " - 文字"字符
  • /mØ你的修改器(多行)。這意味着^將工作每行,而不是隻匹配整個字符串的開始。

編輯

警告:這並不值之間添加逗號!

你可能會更好用:

$json = preg_replace('/("[^"]+")(\s*{[^}]+})/', '$1:$2,', $json); //Add comma for brackets 
$json = preg_replace('/("[^"]+")(\s*"[^"]+")/', '$1:$2,', $json); //Add comma for values 

這也將在同一行工作,但它需要,你從來沒有使用字符{}"其他地方,但令牌(甚至內字符串)。

再次編輯

這似乎這樣的伎倆,可以使用json_decode並解析JSONLint,但它是令人難以置信的醜陋和晦澀:

$json = preg_replace('/(")(\s*{)/m', '$1:$2', $json); //Fix colons after keys with brackets 
$json = preg_replace('/(")([ \t]*")/m', '$1:$2', $json); //Fix colons after keys with values 
$json = preg_replace('/(}\s*$)(\s*")/m', '$1,$2', $json); //Fix commas on lines with brackets 
$json = preg_replace('/("\s*$)(\s*")/m', '$1,$2', $json); //Fix commas on lines with values 
$json = preg_replace('/"[0-9]+":\s*{/m', '{', $json); //Fix invalid keys 
$json = trim($json); 

if ($json[0] == '{' && substr($json, -1) == '}') { 
    $json = '[' . $json . ']'; 
} else { 
    $json = '{' . $json . '}'; 
} 

print_r(json_decode($json)); 

更新

<?php 
    $curl = curl_init(); 
    curl_setopt_array($curl, array(
     CURLOPT_RETURNTRANSFER => true, 
     CURLOPT_URL => "file.txt" 
    )); 
    $json = curl_exec($curl); 

    $json = Horrible_JSON::Parse($json); 
    print_r($json); 

    class Horrible_JSON { 
     public static function Parse($json) { 
      $jsonLength = strlen($json); 
      $realJSON = ''; 
      $isValue = false; 
      for ($i = 0; $i < $jsonLength; $i++) { 
       if ($json[$i] != "\n" && $json[$i] != "\r" && $json[$i] != "\t" && $json[$i] != " ") { 
        if ($json[$i] == '"') { 
         $nextQuote = strpos($json, '"', $i + 1); 
         $quoteContent = substr($json, $i + 1, $nextQuote - $i - 1); 
         if (!$isValue && preg_match('/^[0-9]+$/', $quoteContent)) { 
          $quoteContent = 'int_' . $quoteContent; 
         } 
         $realJSON .= '"' . $quoteContent . '"'; 
         if (!$isValue) { 
          $realJSON .= ':'; 
          $isValue = true; 
         } else { 
          $realJSON .= ','; 
          $isValue = false; 
         } 
         $i = $nextQuote; 
        } else { 
         if ($json[$i] == '{' || $json[$i] == '}') { 
          $isValue = false; 
         } 
         $realJSON .= $json[$i]; 
         if ($json[$i] == '}') { 
          $realJSON .= ','; 
         } 
        } 
       } 
      } 
      $realJSON = str_replace(',}', '}', $realJSON); 
      $realJSON = substr($realJSON, 0, -1); 

      if (substr($realJSON, 0, 1) == '{' && substr($realJSON, -1) == '}') { 
       $realJSON = '[' . $realJSON . ']'; 
      } else { 
       $realJSON = '{' . $realJSON . '}'; 
      } 

      return json_decode($realJSON); 
     } 
    } 
?> 
+0

嗨。感謝您的回答,正則表達式工作得很好,但我認爲我必須找到另一種方式,因爲該文件有一些子鍵,並使用{分隔符而不是[{..我真的不知道你怎麼能做到這一點,因爲它看起來完全像一個主鍵。將編輯我的問題 –

+0

@BobbyShark查看我的最新編輯。這是醜陋的,但它似乎工作。 – h2ooooooo

+0

@BobbyShark最終版本現在在我的答案。它似乎與你的兩個JSON變量一起工作。請永遠不要讓我再次看到此代碼。 – h2ooooooo

0

如果不能訪問原始文件,它很難恢復erse工程師正好是它的結構。

如果這是一次性的,那麼只需使用文本編輯器 - 這很明顯在哪裏插入':'使其看起來像一個JSON文件。

如果您需要處理大量這些數據,請聯繫誰來生產數據,並要求格式的正式定義或將格式更改爲JSON。

如果這兩者都不可能,那麼編寫代碼以注入a:在兩個引用的實體之間是微不足道的。 但你不能保證這是一個有效的文件格式解釋