Search code examples
javajsonregexregex-group

How to retrieve JSON array values from a string with regex in Java


I need to get values from a string with a JSON array using regex String example:

[INFO][2022-11-11] Response body : 
{
   "values":[
      "abc123",
      "def456",
      "xyz789"
   ]
}

So I want to get the values: abc123, def456, xyz789

Please note I'm working with a string (actually it's a log output) so I'm not sure if I can use any libraries for JSON parsing

I'm trying to use the following regex, but getting only the last array value xyz789:

"values"\s*:\s*\[(\s*"(\w+)"\s*,?)*]

My solution in Java

String pattern = "\"values\"\\s*:\\s*\\[(\\s*\"(\\w+)\"\\s*,?)*]" ;

Matcher matcher = Pattern.compile(pattern).matcher(source());
while (matcher.find()) {
    System.out.println("matcher.group() = " + matcher.group());
    System.out.println("matcher.group(1) = " + matcher.group(1));
    System.out.println("matcher.group(1) = " + matcher.group(2)); //xyz789
}
private static String source() {
    String s = "{\"values\": [\n"
            + "        \"abc123\",        \"def456\",      "
            + "          \"xyz789\" ]\n"
            + "    }";

    return s;
}

Solution

  • Example with Jackson

    It can be done almost effortlessly if you would use a library for parsing JSON, like Jackson, Gson, etc., instead of trying to reinvent the wheel.

    Here's an example of how it can be done using Jackson.

    Assume you have the following POJO:

    public class MyPojo {
        private List<String> values;
        
        // getters, setters
    }
    

    That's all you need to deserialize the incoming JSON:

    String jsonStr = // incoming JSON
    
    ObjectMapper mapper = new JsonMapper();
            
    MyPojo pojo = mapper.readValue(jsonStr, MyPojo.class);
    System.out.println(pojo.getValues());
    

    Output:

    [abc123, def456, xyz789]
    

    More over, if you would use platforms like Spring, or Jakarta EE conversion of requests and responses would be done automatically for you.

    If the data is dynamic and introducing a POJO doesn't make much sense, then you can parse it as a Tree, and work with Nodes of that Tree:

    String jsonStr = // incoming JSON
            
    ObjectMapper mapper = new JsonMapper();
    JsonNode node = mapper.readTree(jsonStr).get("values");
    List<String> values = mapper.readerFor(new TypeReference<List<String>>() {}).readValue(node);
    
    values.forEach(System.out::println);
    

    Output:

    abc123
    def456
    xyz789
    

    Parsing Manually

    If you want to do it manually at all costs, here is a way to extract these values by capturing the JSON-array and splitting it:

    String jsonStr = // incoming JSON
            
    Pattern pattern1 = Pattern.compile("\"values\"\\s*:\\s*\\[(.+)]");
    Matcher matcher = pattern1.matcher(jsonStr);
            
    List<String> values = List.of();
            
    if (matcher.find()) {
        values = Arrays.stream(matcher.group(1).split(","))
            .map(s -> s.replaceAll("\"", "").strip())
            .toList();
    }
            
    values.forEach(System.out::println);
    

    Output:

    abc123
    def456
    xyz789