跳至内容

Jixun's Blog 填坑还是开坑,这是个好问题。

PHP 下解析非标准单引号 json 内容

解析《酷我》json 格式内容遇到问题(使用单引号)。

本来是打算直接用现成的解决方案来处理,结果发现 h2ooooooo 的答案 在遇到转义单引号的时候会无限循环;以及最高赞 NikiC 的正则地狱 让我看得头大(看评论好像对嵌入内容处理有毛病?),于是做了个简单的 php 函数把字符串改成用双引号的标准 json 格式。

<?php

define('JSON_SQUOTE', "'");
define('JSON_DQUOTE', '"');

define('JSON_STATE_OUTSIDE_STRING', 1);
define('JSON_STATE_STRING', 2);
define('JSON_STATE_ESCAPE', 3);

function fix_squote_json(string $json): string {
  $result = '';

  $quote = JSON_SQUOTE;
  $state = JSON_STATE_OUTSIDE_STRING;

  $len = strlen($json);
  for ($i = 0; $i < $len; $i++) {
    $c = $json[$i];

    switch ($state) {
      case JSON_STATE_OUTSIDE_STRING:
        if ($c === JSON_SQUOTE || $c === JSON_DQUOTE) {
          $quote = $c;
          $state = JSON_STATE_STRING;
          $result .= JSON_DQUOTE;
        } else {
          $result .= $c;
        }
        break;
      case JSON_STATE_STRING:
        if ($c === $quote) {
          $state = JSON_STATE_OUTSIDE_STRING;
          $result .= JSON_DQUOTE;
        } else if ($c === JSON_DQUOTE) {
          $result .= '\\"';
        } else if ($c === '\\') {
          $state = JSON_STATE_ESCAPE;
        } else {
          $result .= $c;
        }
        break;
      case JSON_STATE_ESCAPE:
        if ($c === JSON_SQUOTE) {
          $result .= JSON_SQUOTE;
        } else {
          $result .= '\\' . $c;
        }
        $state = JSON_STATE_STRING;
        break;
    }
  }

  return $result;
}

知识共享许可协议 本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

评论区