You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中为JSON键值添加双引号的正则表达式问题修复

原有正则的缺陷

你写的正则r'\b[\w:.\/]+\b'有三个根本问题,导致必然出现拆分错误:

  • 依赖单词边界\b做匹配截断:\b只认字母、数字、下划线为单词字符,横杠-、空格、单引号、转义双引号都会被判定为单词边界,直接把连续的日期、带空格的句子拆成多个独立匹配段
  • 匹配字符集不全:[\w:.\/]没有包含横杠、空格、单引号、转义引号这些值里的合法字符,就算去掉单词边界也匹配不到完整的日期和文本内容
  • 完全不识别JSON结构:没有区分键的位置、值的位置、结构分隔符(大括号、中括号、逗号、冒号),属于全局盲目匹配,很容易破坏JSON结构。
可行修复方案

不要靠单个正则全局替换硬凑,这类类JSON数据的结构符号({、}、[、]、:、,)都是完全符合标准的,问题只出在键、非数字值没加双引号,按结构逐字符遍历处理更可靠,不会出现拆分错误。
完整Dart实现代码如下:

import 'dart:convert';

String fixUnstandardJson(String input) {
  // 先压缩无关空白,避免原始字符串里的换行、多余空格干扰解析
  input = input.replaceAll(RegExp(r'\s+'), ' ').trim();
  StringBuffer writeBuffer = StringBuffer();
  bool isInValueZone = false;
  StringBuffer contentBuffer = StringBuffer();

  for (int i = 0; i < input.length; i++) {
    String currentChar = input[i];
    // 保留已经转义的双引号,不做拆分
    if (currentChar == r'\' && i + 1 < input.length && input[i + 1] == '"') {
      contentBuffer.write(currentChar);
      contentBuffer.write(input[i + 1]);
      i++;
      continue;
    }
    // 遇到JSON结构分隔符时,处理之前缓存的键/值内容
    if (currentChar == '{' || currentChar == '}' || currentChar == '[' || currentChar == ']' || currentChar == ':' || currentChar == ',') {
      if (contentBuffer.isNotEmpty) {
        String content = contentBuffer.toString().trim();
        contentBuffer.clear();
        if (content.isNotEmpty) {
          if (isInValueZone) {
            // 值区域:纯整数保留数字类型,其余内容全部包裹双引号
            if (RegExp(r'^-?\d+$').hasMatch(content)) {
              writeBuffer.write(content);
            } else {
              writeBuffer.write('"$content"');
            }
            isInValueZone = false;
          } else {
            // 键区域:所有键统一包裹双引号
            writeBuffer.write('"$content"');
          }
        }
      }
      // 冒号标记后续进入值区域
      if (currentChar == ':') {
        isInValueZone = true;
      }
      writeBuffer.write(currentChar);
      continue;
    }
    // 普通字符存入内容缓存
    contentBuffer.write(currentChar);
  }
  // 处理末尾剩余的内容
  if (contentBuffer.isNotEmpty) {
    String content = contentBuffer.toString().trim();
    if (content.isNotEmpty) {
      if (isInValueZone) {
        if (RegExp(r'^-?\d+$').hasMatch(content)) {
          writeBuffer.write(content);
        } else {
          writeBuffer.write('"$content"');
        }
      } else {
        writeBuffer.write('"$content"');
      }
    }
  }
  // 解析后输出带缩进的标准可读JSON
  final parsedJson = jsonDecode(writeBuffer.toString());
  return const JsonEncoder.withIndent('   ').convert(parsedJson);
}

调用示例:

void main() {
  const rawData = r'{key_string:value,key_object-1:[{key_double:99.99999999,key_float:99.99,key_datetime:2022-06-13 11:47:35},{key_long:He \"Ali\" does\'t like me,lng:67.1229545,key_date:2022-06-13}],key_int:999999,key_object-2:[{key_double:99.99999999,key_float:99.99,key_datetime:2022-06-13 11:47:35},{key_long:He \"Ali\" does\'t like me,lng:67.1229545,key_date:2022-06-13}]}';
  final standardJson = fixUnstandardJson(rawData);
  print(standardJson);
}

这个实现可以完全覆盖你提到的错误场景:

  • 带横杠、空格的日期/时间值会被完整识别,不会被拆分加引号
  • 带空格、转义双引号、单引号的文本值会被完整包裹
  • 整数类型值会保留数字格式,不会被误转成字符串
  • 最终输出的JSON可以直接被所有标准JSON解析器识别,缩进格式和你给出的目标效果完全一致。

内容的提问来源于stack exchange,提问作者Muhammad Hassan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:36:21