使用正则表达式将字符串转换为JSON

时间:2016-01-15 12:51:50

标签: php json regex

我有一个这样的字符串:

{
"XXX"       "XXX"
"XXX"       "XXX"
"XXX"
{
    "XXX"       "XXX"
    "XXX"       "XXX"
    "XXX"
    {
        "XXX"       "XXX"
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
    }
    "XXX"       "XXX"
}
"XXX"
{
    "XXX"       "XXX"
    "XXX"
    {
        "XXX"       "XXX"
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
    }
    "XXX"       "XXX"
}
"XXX"
{
    "XXX"       "XXX"
    "XXX"
    {
        "XXX"       "XXX"
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
    }
    "XXX"       "XXX"
}
"XXX"
{
    "XXX"       "XXX"
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
        "XXX"       "XXX"
    }
    "XXX"       "XXX"
}
"XXX"
{
    "XXX"
    {
        "XXX"       "XXX"
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       ""
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       ""
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       ""
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       ""
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       ""
    }
    "XXX"
    {
        "XXX"       "XXX"
        "XXX"       ""
    }
  }
}

它看起来像JSON,但它并不是:它缺少所有逗号(',')和所有冒号(":" )。我试图找到一种方法来解析它并变成一个有效的JSON字符串。

我的猜测是使用制表符和换行符在字符串中查找我的方式,但到目前为止我无法将其转换为有效的JSON。

我想出了这个,但是我相信效率不高或安全失败:

$e = explode( "\n", $string );
foreach( $e as $k => $l ) {

$next = str_replace( "\t", '', $e[ $k + 1 ] );
$isParam = strstr( $l, "\"\t\t\"" );
$currentClean = str_replace( "\t", '', $l );

if ( $isParam )
    $e[ $k ] = str_replace( "\"\t\t\"", '":"', $l );

if ( $isParam && $next != '}' )
    $e[ $k ] .= ',';

if ( $currentClean == '}' && $next != '}' && $next )
    $e[ $k ] .= ',';

if ( preg_match( '#^"(.*)"$#', $currentClean ) && !$isParam )
    $e[ $k ] .= ':';

}
$json = implode("\n", $e);

如何改善这个?

2 个答案:

答案 0 :(得分:2)

问题是你手边有几个替换...所以我的答案有几个调用(我尝试使用所有文本,不需要将每行分开,只需输入全文)。

//For the ":" before "}" and keys
$alltext = preg_replace("/(\"\w+\")\s+(\{|(\"\w*\"))/", "$1:$2", $alltext);

//For "," at the ends of the values:keys
$alltext = preg_replace("/(\"\w*\":\"\w*\")(?!\s+(\}|\{))/", "$1$2,", $alltext);

//For the "," at the end of each "}" that has a value after
$alltext = preg_replace("/(\})(\s+\")/", "$1,$2", $alltext);
PD:不知道你的价值是什么,这就是我在答案中留下\ w +的原因。如果它有用,请告诉我。

PD2:您可以在phpliveregex

尝试

答案 1 :(得分:1)

并非完全完美,但却是一个非常好的开始:

// Replace '"xxx" "xxx"' by '"xxx": "xxx",'
$string = preg_replace('/("[^"]+")\s+("[^"]*")/','$1: $2,',$string);

// Replace '} "xxx" {' with "} "xxx": {", accept "}" and "{" for start/end
$string = preg_replace('/([{}])(\s+)("[^"]+")\s+([{}])/','$1$2$3:$4',$string);

// Replace ", {" by " {"
$string = preg_replace('/,(\s*[}{])/','$1',$string);

echo $string;

问题:第一个正则表达式在每场比赛后放置,。不应该是值列表中最后一个值的情况,如下所示:

...
"XXX":{
   "XXX": "XXX",
   "XXX": "", <-- Wrong!
}
...

可以在http://sandbox.onlinephpfunctions.com/code/36f618bbeaaa861a88b873144e25232c5ba2c8e1

找到工作代码示例