将数组字符串表示转回数组:JS报错原因及Java实现方法
问题分析与解决方案
一、JavaScript代码的核心问题
你这段代码报错的根本原因是原始字符串根本不是标准JSON格式,JSON.parse只能解析严格符合JSON语法的字符串,而你的输入有几个明显不符合JSON规范的地方:
- JSON要求对象的键必须用双引号包裹(比如
"name"),但你的字符串里是name; - JSON用冒号
:分隔键和值,你用的是=; - 字符串里的空格、方括号的写法也完全不符合JSON语法规则。
所以直接用JSON.parse去解析,肯定会抛出语法错误。
二、修正后的JavaScript实现
我们可以手动解析这个自定义格式的字符串,转换成标准的JavaScript对象数组,代码如下:
let string = "[name = preload cacheHits = 30 onDiskHits = 4 inMemoryHits = 26 misses = 0 size = 2913 averageGetTime = 0.1 evictionCount = 0 ]\n[ name = information cacheHits = 0 onDiskHits = 0 inMemoryHits = 0 misses = 0 size = 0 averageGetTime = 0.0 evictionCount = 0 ]"; // 按换行分割,清理每个项的方括号和多余空格 const itemStrings = string.split('\n').map(item => item.trim().replace(/^\[|\]$/g, '').trim() ); // 解析每个项为对象 const resultArray = itemStrings.map(item => { const statsObj = {}; // 正则匹配键值对:支持字母数字键,值可以是数字(含小数)或单词 const keyValueRegex = /(\w+)\s*=\s*(\d+\.?\d*|\w+)/g; let match; while ((match = keyValueRegex.exec(item)) !== null) { const key = match[1]; let value = match[2]; // 尝试把值转为数字(整数/浮点数) if (!isNaN(value)) { value = parseFloat(value); } statsObj[key] = value; } return statsObj; }); console.log(resultArray);
这段代码的逻辑很清晰:先把原始字符串拆成单个统计项,再用正则提取每个键值对,自动转换数字类型,最后组装成对象数组。
三、Java实现方案
当然可以用Java实现这个转换,思路和JavaScript类似,用正则提取键值对并转换类型,示例代码如下:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CacheStatsParser { public static void main(String[] args) { String input = "[name = preload cacheHits = 30 onDiskHits = 4 inMemoryHits = 26 misses = 0 size = 2913 averageGetTime = 0.1 evictionCount = 0 ]\n[ name = information cacheHits = 0 onDiskHits = 0 inMemoryHits = 0 misses = 0 size = 0 averageGetTime = 0.0 evictionCount = 0 ]"; // 按换行分割每个统计项 String[] itemArray = input.split("\n"); List<Map<String, Object>> resultList = new ArrayList<>(); // 定义匹配键值对的正则表达式 Pattern kvPattern = Pattern.compile("(\\w+)\\s*=\\s*(\\d+\\.?\\d*|\\w+)"); for (String item : itemArray) { // 清理掉前后的方括号和多余空格 String cleanItem = item.trim().replaceAll("^\\[|\\]$", "").trim(); Matcher matcher = kvPattern.matcher(cleanItem); Map<String, Object> statsMap = new HashMap<>(); while (matcher.find()) { String key = matcher.group(1); String valueStr = matcher.group(2); // 尝试转换为数字,失败则保留字符串 try { if (valueStr.contains(".")) { statsMap.put(key, Double.parseDouble(valueStr)); } else { statsMap.put(key, Integer.parseInt(valueStr)); } } catch (NumberFormatException e) { statsMap.put(key, valueStr); } } resultList.add(statsMap); } // 打印结果 for (Map<String, Object> stats : resultList) { System.out.println(stats); } } }
这段Java代码会把输入字符串转换成List<Map<String, Object>>,和JavaScript的对象数组结构等价,同样会自动识别数字类型,非数字值保留为字符串。
内容的提问来源于stack exchange,提问作者skr




