【问题标题】:Converting multiline, indented json to single line using javascript使用javascript将多行缩进的json转换为单行
【发布时间】:2026-02-12 13:00:01
【问题描述】:

我想出了以下函数,用于将多行、缩进良好的 json 转换为单行

function(text) {
    var outerRX = /((?:".*?")|(\s|\n|\r)+)/g,
        innerRX = /^(\s|\n|\r)+$/;

    return text.replace(outerRX, function($0, $1) {
        return $1.match(innerRX) ? "" : $1 ;
    });
}

任何人都可以想出更好的东西,无论是在效率方面还是在修复我的实现中存在的错误(例如解析时我的中断

{
    "property":"is dangerously
             spaced out" 
}

{
    "property":"is dangerously \" punctuated" 
}

【问题讨论】:

  • 您是否正在尝试缩小 JSON?为此存在开源解决方案。
  • 理想情况下,是的,它会缩小服务器端,但现在没有人有时间这样做,所以我必须有一个易于维护(即缩进、多行)的 json 文件完全按原样传递给 jQuery.ajax
  • 你看过jsmin吗?您可以使用server sideclient side 两种版本。
  • jsmin 的问题在于它缩小了 javascript,但 json 只是 javascript 的一个子集,所以我敢打赌它会运行在这种情况下不需要的大量正则表达式。因此,虽然它无疑比我的函数少错误,但它可能比非错误的、单一用途的 json 缩小函数效率低。另外,我不确定您在上面发布的客户端版本的链接是客户端的 - 我能找到的所有链接都指向 C 和 .exe 文件 - 都是服务器端
  • 破解打开jsmin,拿走你想要的。

标签: javascript regex json indentation


【解决方案1】:

对于此类问题,我遵循添加正则表达式只会给您带来两个问题的格言。这是一个足够简单的解析问题,所以这里有一个解析解决方案:

var minifyJson = function (inJson) {
  var outJson, // the output string
      ch,      // the current character
      at,      // where we're at in the input string
      advance = function () {
        at += 1;
        ch = inJson.charAt(at);
      },
      skipWhite = function () {
        do { advance(); } while (ch && (ch <= ' '));
      },
      append = function () {
        outJson += ch;
      },
      copyString = function () {
        while (true) {
          advance();
          append();
          if (!ch || (ch === '"')) {
            return;
          }
          if (ch === '\\') {
            advance();
            append();
          }
        }
      },
      initialize = function () {
        outJson = "";
        at = -1;
      };

  initialize();
  skipWhite();

  while (ch) {
    append();
    if (ch === '"') {
      copyString();
    }
    skipWhite();
  }
  return outJson;
};

请注意,代码没有任何错误检查以查看 JSON 格式是否正确。唯一的错误(字符串没有右引号)被忽略。

【讨论】:

  • 我很不愿意承认使用正则表达式的失败,但发现 javascript 正则表达式缺乏对lookbehind 的支持是一个真正的障碍,所以我将尝试你的方法 - 非常感谢分享它。
【解决方案2】:

这修复了问题中的两个错误,但可能不是很有效

function(text) {
    var outerRX = /((?:"([^"]|(\\"))*?(?!\\)")|(\s|\n|\r)+)/g,
    innerRX = /^(\s|\n|\r)+$/;

    return text.replace(outerRX, function($0, $1) {
        return $1.match(/^(\s|\n|\r)+$/) ? "" : $1 ;
    });
}

【讨论】:

    最近更新 更多