1

Below code :

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

public class TestCode {

    private Map<String, String> getMappedValues(final String line) {
        final Map<String, String> mappedValues = new HashMap<String, String>();

        final Pattern p = Pattern.compile("\"(.*?)\"");
        final Matcher m = p.matcher(line);

        while (m.find()) {
            for (String strTemp : m.group().split(",")) {
                String key = strTemp.split("=")[0].replace("$", "").replace("\"", "").trim();
                String value = strTemp.split("=")[1].replace("\"", "").trim();
                mappedValues.put(key, value);
            }
        }

        return mappedValues;
    }

    public static void main(String args[]) {

        final String str = "aaaa,\"$0 = test1, $1 = test2\",a,b,c";

        final TestCode testCode = new TestCode();
        Map<String, String> mappedValues = testCode.getMappedValues(str);
        mappedValues.entrySet().forEach(entry -> {
            System.out.println(entry.getKey() + " " + entry.getValue());
        });

    }

}

prints :

0 test1
1 test2

The string \"$0 = test1, $1 = test2\" is parsed from the string

"aaaa,\"$0 = test1, $1 = test2\",a,b,c"

The string \"$0 = test1, $1 = test2\" is then converted to a map where key is left of = and value is right of =

A variable number of key value pairs can occur.

I'm just concentrating on the happy path for now.

Is there a cleaner method of parsing the values rather than using :

String key = strTemp.split("=")[0].replace("$", "").replace("\"", "").trim();
String value = strTemp.split("=")[1].replace("\"", "").trim();

?

thepen
  • 371
  • 1
  • 11

1 Answers1

1

Since you are already using regular expressions, you should do away with all the String.split()s by using a regex that captures the $key = value pairs too using sub-sequence capturing groups.

Here's my regex without the \ escaped for readability. Notice the use of (?:) to create a non-capturing group; only num and value in $num = value pairs are captured as subgroups.

"\$(\d+)\s=\s(\w+)(?:,\s\$(\d+)\s=\s(\w+))*"

Using the above regex the for loop gets greatly simplified.

final Pattern p = Pattern.compile("\"\\$(\\d+)\\s=\\s(\\w+)(?:,\\s\\$(\\d+)\\s=\\s(\\w+))*\"");
final Matcher m = p.matcher(line);

while (m.find()) {
    for (int i = 1; i <= m.groupCount(); i++) {
        mappedValues.put(m.group(i), m.group(++i));
    }
}
Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89