-4

I am trying to write code to extract some values from string following some pattern. Basically a the key and value from json where value is enclosed in {{value}}

In the below code:

String jsonString = "{\"title\":\"{{string_64|dsm_title}}\",\"code\":\"{{string_16|dsm_code}}\",\"enabled\":true,\"enableAdvanceFilter\":false,\"deleteAfterScheduledTime\":false,\"enableDataStoreLog\":false}";
        String patternString = "[\"](?<key>.*)[\"][:][? ]?.*[{][{](?<value>.*)[}][}]";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(jsonString);
        HashMap<String, Object> allMatches = new HashMap<>();
        while (matcher.find()) {
            allMatches.put(matcher.group("value"), matcher.group("key"));
        }
        System.out.println(allMatches);

I am expecting output as:

string_64|dsm_title -> title
string_16|dsm_code -> code

But the output it is giving me is:

string_16|dsm_code -> title":"{{string_64|dsm_title}}","code

Please help me in corretcting the regex. Please dont provide solution regarding parsing it to json and all. That is not the solution I need.

VIBHOR GOYAL
  • 473
  • 1
  • 6
  • 22
  • 6
    Don’t parse JSON with regex. Use a JSON parser. – Biffen Apr 01 '20 at 07:59
  • I am not parsing json. I am trying to extract some string following a pattern. Dont consider this as a json. Consider it as a simple string. – VIBHOR GOYAL Apr 01 '20 at 08:01
  • 1
    It’s a really strange idea to map from value to key. This implies that in case of two keys having the same value, only one will be in the result map. – Holger Apr 01 '20 at 10:39

1 Answers1

1

Since this is JSON that you're working with, you should really use a JSON parser to turn your JSON string into an object or map, these parsers come in-built with functions to turn JSON Strings into maps - Good examples are GSON and Java's own JSON parser. Right now, you're - as it's often said - "Reinventing the wheel", adding complexity by writing code already made by others, probably much more efficient than for instance a RegEx approach can be. See how to go from a JSONObject to a map using something like Jackson here

However, if you really want to use RegEx for this issue, I would use a RegEx similar to this: (?>\\\")(?<key>.*?)(?>\\\":\\\"\\{\\{)(?<value>.*?)(?>\\}\\}\\\"). You can see it working with your code here. This will get you the output {string_64|dsm_title=title, string_16|dsm_code=code} since you were printing the map directly in your example.

If the link to the snippet doesn't work for you, here's the change in your given code code directly:

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Main {
  public static void main(String[] args) {
    String jsonString = "{\"title\":\"{{string_64|dsm_title}}\",\"code\":\"{{string_16|dsm_code}}\",\"enabled\":true,\"enableAdvanceFilter\":false,\"deleteAfterScheduledTime\":false,\"enableDataStoreLog\":false}";
    String patternString = "(?>\\\")(?<key>.*?)(?>\\\":\\\"\\{\\{)(?<value>.*?)(?>\\}\\}\\\")";

    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(jsonString);

    HashMap<String, Object> allMatches = new HashMap<>();
    while (matcher.find()) {
      allMatches.put(matcher.group("value"), matcher.group("key"));
    }

    System.out.println(allMatches);
  }
}

What also kind of confuses me is that the portion you name in your RegEx as "key" you subsequently use and the value in your map, and that which you name "value" in your RegEx you use as the map's key. You may want to reconsider your naming conventions and approach in general, as it may make reading your code harder for people in the future.

Toastyblast
  • 140
  • 7