使用Regex在Java中拆分嵌套JSON

时间:2013-07-27 22:57:08

标签: java regex json split

我有一个JSON字符串:

{name:"X",age:{dob:"DD MMM",year:YYYY}}

我需要Hashtable<String, String>对,如:

name: "X"
age: {dob:"DD MMM",year:YYYY}

我目前正在使用

string.substring(1,string.length() - 2).split(",");

如何使用正则表达式实现此目的?

3 个答案:

答案 0 :(得分:5)

描述

提供您的JSON文本不会嵌套在示例文本中显示的级别之外,那么此表达式将:

  • 捕获属性名称
  • 捕获属性值
  • 会将值数组保持在一起,只返回顶级

(?:,|\{)?([^:]*):("[^"]*"|\{[^}]*\}|[^},]*)

enter image description here

实施例

Live Demo

示例文字

{name:"X",age:{dob:"DD MMM",year:YYYY}}

<强>代码

String sourcestring = "source string to match with pattern";
Pattern re = Pattern.compile("(?:,|\\{)?([^:]*):(\"[^\"]*\"|\\{[^}]*\\}|[^},]*)",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
Matcher m = re.matcher(sourcestring);

<强>匹配

[0][0] = {name:"X"
[0][1] = name
[0][2] = "X"

[1][0] = ,age:{dob:"DD MMM",year:YYYY}
[1][1] = age
[1][2] = {dob:"DD MMM",year:YYYY}

答案 1 :(得分:3)

以下是如何通过4行完成整个操作:

Map<String, String> map = new HashMap<String, String>();
String[] parts = json.replaceAll("^\\{|\\}$","").split("\"?(:|,)(?![^\\{]*\\})\"?");
for (int i = 0; i < parts.length -1; i+=2)
    map.put(parts[i], parts[i+1]);

其工作原理如下:

  1. 头部和尾部的牙箍被移除,因为我们不能轻易将它们分开 - 它们是垃圾
  2. 输入由冒号或逗号分隔,可选地在引号前面/后跟(这整齐地消耗引号),但仅当下一个大括号不是紧支撑时(意味着我们不是在嵌套术语中)
  3. 在分割结果上循环2,将名称/值对放入地图
  4. 这是一些测试代码:

    public static void main(String[] args) throws Exception {
        String json = "{name:\"X\",age:{dob:\"DD MMM\",year:YYYY}}";
        Map<String, String> map = new HashMap<String, String>();
        String[] parts = json.replaceAll("^\\{|\\}$","").split("\"?(:|,)(?![^\\{]*\\})\"?");
        for (int i = 0; i < parts.length -1; i+=2)
            map.put(parts[i], parts[i+1]);
        System.out.println(map.size() + " entries: " + map);
    }
    

    输出:

    2 entries: {age={dob:"DD MMM",year:YYYY}, name=X}
    

答案 2 :(得分:-3)

这只有在支持recursrion的情况下才有可能,但遗憾的是它不在java中。

如果支持recursrion,则此正则表达式会执行此操作:(?=({(?>[^{}]|(?1))+}))

现场演示:http://regex101.com/r/pH7rV8