1

I have a key-value string with the following pattern in my Java program:

[key1]value1[key2]value2[key3]value3

where keys and values are Strings.

How can I parse this string and take key-value pairs in to a Map?

Firstly, by splitting the string with a regex, it should give the values and then parsing the string with the same regex could provide the keys. Coming up with this regex is the main issue of mine as I've hardly used regex.

Amos M. Carpenter
  • 4,848
  • 4
  • 42
  • 72
Tom
  • 23
  • 3
  • Do the keys or values have a definite data structure? – ifly6 Feb 24 '16 at 04:57
  • Trying to come up with a regex to search words starts with "[" and ends with "]". It is embarrassing still couldn't come up with the regex. – Tom Feb 24 '16 at 05:02
  • keys and values are simply strings, keys are wrapped with "[]" values present always next to the keys – Tom Feb 24 '16 at 05:03
  • please check if this helps http://stackoverflow.com/questions/2403122/regular-expression-to-extract-text-between-square-brackets – Edi Feb 24 '16 at 05:07
  • Thanks Edi, The regex given on that question works well, now I can find the keys.. Thanks :) – Tom Feb 24 '16 at 05:10
  • Might want to look at `StringTokenizer`. You could tokenize at `]` and `[` – Ashwin Gupta Feb 24 '16 at 05:33

3 Answers3

3

A regex can split the string into parts, and a simple loop can add it to the map;

    String input = "[key1]value1[key2]value2[key3]value3";

    // Gives ["", "key1", "value1", "key2", "value2", ...]
    String[] data = input.split("\\[|\\]");

    Map<String, String> dict = new HashMap<>();

    for(int i=1; i<data.length; )
        dict.put(data[i++], i == data.length ? "" : data[i++]);

The reason for the condition in the put is that `String.split´ removes empty values at the end, which means that if the last value were empty it would not be included in the array. The condition just checks if the value exists, and if not it replaces it with the empty string.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294
  • This works perfectly and gives the solution with minimum number of lines. Other answers should work as well, however this answer deserves acceptance.. – Tom Feb 24 '16 at 06:38
  • BTW, whats the purpose of this concatenation? input.concat("[a") It works without this. Any instance this doesn't work without concat ? – Tom Feb 24 '16 at 07:15
  • @Tom The only thing the concat does is solve when the last value is empty, that is, `[key1]value1[key2]`. `strip` removes the last empty values which causes trouble. I agree it didn't look nice, I replaced it with a less memory intensive check in the loop instead. – Joachim Isaksson Feb 24 '16 at 07:18
1

You can easily parse using two different regex for :

  1. Key Extract regEx is \\[(.*?)]
  2. Value Extract regEx is \\](.*?)\\[|\\](.*)

Example:

public class KeyValueParse {

    public static void main(String[] args) {
        String input = "[key1]value1[key2]value2[key3]value3";

        String keyRegEx = "\\[(.*?)]";
        String valueRegEx = "\\](.*?)\\[|\\](.*)";

        Map<String, String> map = new HashMap<>();

        Pattern keyPattern = Pattern.compile(keyRegEx);
        Pattern valuePattern = Pattern.compile(valueRegEx);

        Matcher keyMatcher = keyPattern.matcher(input);
        Matcher valueMatcher = valuePattern.matcher(input);

        System.out.println("-----KeyValue pairs-------");
        while (keyMatcher.find() && valueMatcher.find()) {
            String key = keyMatcher.group().replaceAll("\\[|\\]", "");
            String value = valueMatcher.group().replaceAll("\\[|\\]", "");

            System.out.println("Key Pair : [ key = " + key + ", value= " + value + "]");
            //put key and value in map
            map.put(key, value);
        }
    }
}
Bhuwan Prasad Upadhyay
  • 2,916
  • 1
  • 29
  • 33
1

You could try this:

String str = "[key1]value1[key2]value2[key3]value3";
String[] strings = str.split("\\[");
Map<String, String> map = new HashMap<>();
for (String string : strings) {
    if (string.length() > 0) {
        String[] array = string.split("\\]");
        map.put(array[0], array[1]);
    }
}
System.out.println(map);

And it is the result:

{key1=value1, key2=value2, key3=value3}
Bahramdun Adil
  • 5,907
  • 7
  • 35
  • 68