You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

将数组字符串表示转回数组: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

火山引擎 最新活动