PHP如何解析json格式的文件
我需要解析一个看起来像JSON文件的文件,但它不是。它缺少PHP如何解析json格式的文件,php,json,parsing,Php,Json,Parsing,我需要解析一个看起来像JSON文件的文件,但它不是。它缺少:字符,因此我无法使用json\u decode解析它。我不是这个文件的所有者,所以我不得不接受它。。如何解析此文件?有什么想法吗?多谢各位 "sound_materials" { "common" { "value" "0" "start_drag_sound" "ui.inv_pickup" "end_drag_sound" "ui.inv
:
字符,因此我无法使用json\u decode
解析它。我不是这个文件的所有者,所以我不得不接受它。。如何解析此文件?有什么想法吗?多谢各位
"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建议的正则表达式,它非常适合格式化文件。我的错误是,在上面的示例中,我只放置了一个具有1行键的零件
我在文件的其他部分有子键,在这种情况下,我需要为子键添加[]分隔符..: 无论格式是什么,这绝对是afwul,因为它不是-json。如果您可以保证它始终与OP中的一模一样(每行一个键),那么您可以通过执行以下操作来修复它:
$json = preg_replace('/^(\s*"[^"]+")/m', '$1:', $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);
}
}
?>
-行必须从这里开始^
-捕获组(这就是(\s*“[^”]+”
所指的)匹配:$1
-空格/制表符/换行符重复0次或更多次\s*
-文字“
字符”
-任何非[^”]+
重复1次或多次的字符“
-文字“
字符”
我们的修饰符(多行)。这意味着/m
将每行工作,而不是只匹配整个字符串的开头^
<?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);
}
}
?>
警告:这不会在值之间添加逗号
您最好使用:
$json = preg_replace('/("[^"]+")(\s*{[^}]+})/', '$1:$2,', $json); //Add comma for brackets
$json = preg_replace('/("[^"]+")(\s*"[^"]+")/', '$1:$2,', $json); //Add comma for values
这也适用于一行,但它要求除了标记(甚至在字符串内部)之外,不要在任何其他地方使用字符{
、}
或“
再次编辑:
<?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);
}
}
?>
这似乎可以做到这一点,可以使用json\u解码
并解析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);
}
}
?>
无论格式是什么,这绝对是afwul,因为它不是-json。如果您可以保证它始终与OP中的一模一样(每行一个键),那么您可以通过执行以下操作来修复它:
$json = preg_replace('/^(\s*"[^"]+")/m', '$1:', $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);
}
}
?>
^
-行必须从这里开始
(\s*“[^”]+”
-捕获组(这就是$1
所指的)匹配:
\s*
-空格/制表符/换行符重复0次或更多次
“
-文字”
字符
[^”]+
-任何非“
重复1次或多次的字符
“
-文字”
字符
/m
我们的修饰符(多行)。这意味着^
将每行工作,而不是只匹配整个字符串的开头
编辑:
<?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);
}
}
?>
警告:这不会在值之间添加逗号
您最好使用:
$json = preg_replace('/("[^"]+")(\s*{[^}]+})/', '$1:$2,', $json); //Add comma for brackets
$json = preg_replace('/("[^"]+")(\s*"[^"]+")/', '$1:$2,', $json); //Add comma for values
这也适用于一行,但它要求除了标记(甚至在字符串内部)之外,不要在任何其他地方使用字符{
、}
或“
再次编辑:
<?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);
}
}
?>
这似乎可以做到这一点,可以使用json\u解码
并解析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);
}
}
?>
如果无法访问原始文件,则很难对其结构进行精确的逆向工程
如果这是一次性的,那么只需使用一个文本编辑器——很明显,在哪里插入“:”使其看起来像一个JSON文件
如果您需要处理大量这些数据,那么请与生成数据的人联系,并要求他们提供格式的正式定义,或者让他们将格式更改为JSON
如果这两种方法都不可行,那么编写代码在2个引用实体之间插入:就很简单了。但是您不能保证这是对文件格式的有效解释,如果不访问原始文件,则很难对其结构进行精确的反向工程
如果这是一次性的,那么只需使用一个文本编辑器——很明显,在哪里插入“:”使其看起来像一个JSON文件
如果您需要处理大量这些数据,那么请与生成数据的人联系,并要求他们提供格式的正式定义,或者让他们将格式更改为JSON
如果这两种方法都不可行,那么编写代码在2个引用实体之间插入:就很简单了。但是您不能保证这是对文件格式的有效解释,因为它不是json。。。它是一个数组吗?还是一根绳子?或者wat?你必须做一些繁重的字符串分析。看看正则表达式怎么样?你可以搜索并替换引号内有两个字符串的行,用空格分隔,然后用冒号替换空格(或者:向文件供应商抱怨并加载足够多的文件,如果文件应该是json,则供应商可以修复此问题,如果不是json,则可以向您提供解析器)。如果你一直在写自己的语法分析器:查阅一些如何在互联网站上创建语法分析器的方法。它不是json…它是在数组中?还是字符串?还是wat?你必须做一些繁重的字符串分析。看看正则表达式如何?你可以搜索并替换一行,其中有两个字符串,用引号隔开,用空格隔开,然后替换带冒号的空格。呃,在我看来,手动编写自己的解析器似乎是唯一明智的方法(或者:向文件供应商抱怨,如果文件应该是json,那么供应商可以修复这个问题,如果文件不是json,那么就向您提供一个解析器)。如果你一直在写自己的语法分析器:查阅一些如何在上面创建语法分析器的指南