【问题标题】:Using regex to turn a string into JSON [closed]使用正则表达式将字符串转换为 JSON [关闭]
【发布时间】:2016-01-15 12:51:49
【问题描述】:

我有一个这样的字符串:

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

如何改进?

【问题讨论】:

  • 字符串从何而来?
  • @AlexAndrei 它来自一个我无法控制的服务。
  • 您应该要求提供者将此垃圾修复为有效格式。如果你开始解析这些东西,它会变得更糟,并且提供者永远不会习惯有效的格式。特别是如果您为服务付费。
  • 您的“json”示例似乎已损坏。 24 { 和只有 23 } 括号。
  • 我刚回来发现问题 ON HOLD,所以无法发布答案。我观察到如果我在 REVERSE ORDER 中处理文本行,这个问题会更容易解决。我的解决方案使用了四个正则表达式:'\}'、'(\".*?\")\s+(\".*\")'、'^\s*(\".*?\") (\s*)$', '^\{'

标签: php json regex


【解决方案1】:

问题是你手头有几个替换......所以我的回答伴随着几个电话(我尝试使用所有文本,它不需要每行分开,只需输入全文)。

//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试试看

【讨论】:

  • 按预期工作,除了在我们有“key”:“value”的情况下不添加“:”。您的代码返回“键”、“值”。结果在:pastebin.com/fgiiNV4v
  • 已修复,我完全忘记了钥匙。比您的初始选项更快吗?
  • 它很可能更快。至少,它更优雅......!我仍然有一个问题,在第 108 行。试图找出它是什么。结果:pastebin.com/t718tcrK
  • 我现在注意到,初始输入中缺少“}”,@maxhb 评论中有 24 个 { 并且只有 23 个 }
  • 确实如此。我想是在我粘贴到 Stackoverflow 的编辑器之类的时候。谢谢你。效果很好:)
【解决方案2】:

不完全完美,但一个非常好的开始:

// 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找到

【讨论】:

  • 确实是好的开始。除了那个逗号,它应该得到一切。我会试着看看我是否可以改进你的代码。谢谢!
  • 添加了第三个正则表达式来处理, ;-)
  • Oups,一开始我没有注意到:它不会在这种情况下添加逗号:“key”:{“key”:“value”},“key”:。 ...(“}”后面的逗号)。
猜你喜欢
  • 2021-09-16
  • 2017-10-29
  • 1970-01-01
  • 2019-12-20
  • 2018-10-08
  • 2017-05-15
  • 2012-01-28
  • 2022-11-18
  • 1970-01-01
相关资源
最近更新 更多