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
相关产品推荐
相关产品推荐

