1

input file :

key1=1
key2=start(a
b
c=
d)end
key3=d=e=f
somekey=start(123)end
morekey=start(1
2)end
key=jj

output

key1    -> 1
key2    -> a
           b
           c=
           d
key3    -> d=e=f
somekey -> 123
morekey -> 1
           2
key     -> jj

Request : Trying in java. Can't use java.util.Properties, regex is fine but not preferred, prefer StringUtils.substringBetween, but regex will do. How can I traverse through multiple lines and preserve newlines too. The following obviously dont work for multilines. Was going to try regex, but only if a more elegant way is not possible.

    String[] str = line.split("=", 2);
    StringUtils.substringBetween(line,startString,endString)); 
juntao
  • 13
  • 2

3 Answers3

1

did you mean something like this :

String str = "key1=1\n"
        + "key2=start(a\n"
        + "b\n"
        + "c=\n"
        + "d)end\n"
        + "key3=d=e=f\n"
        + "somekey=start(123)end\n"
        + "morekey=start(1\n"
        + "2)end\n"
        + "key=jj";
System.out.println(str.replaceAll("start\\(|\\)end", "")
        .replaceAll("(\\w{2})=", "$1\t-> ")
        .replaceAll("(\n\\w)", "\t$1"));
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • What is it called when you do stuff like this: "(\\w{2})="? I really want to learn about it, but dont know what to google – Elias Fyksen May 12 '17 at 20:20
  • i makes this `"(\\w{2})="` for this special case `c=` @EliasFyksen – Youcef LAIDANI May 12 '17 at 20:22
  • why? because there are a key followed by = so to avoid to replace this `c=` i used `"(\\w{2})="` so it will replace every = with this groupe `(\\w{2})` that i represent it `$1` and the `=` with `->\s` @EliasFyksen ? you get it? – Youcef LAIDANI May 12 '17 at 20:26
  • What i ment was: what is this technique called. Is it regex? PS: noob here – Elias Fyksen May 12 '17 at 20:29
  • 1
    ahh read about groups @EliasFyksen read this http://stackoverflow.com/questions/17969436/java-regex-capturing-groups – Youcef LAIDANI May 12 '17 at 20:31
0

One way to solve this is to write your own parser. For example:

public static final String START = "start(";
public static final String END = ")end";

// ...

Scanner scanner = new Scanner(
        "key1=1\n" +
        "key2=start(a\n" +
        "b\n" +
        "c=\n" +
        "d)end\n" +
        "key3=d=e=f\n" +
        "somekey=start(123)end\n" +
        "morekey=start(1\n" +
        "2)end\n" +
        "key=jj");

Map<String, String> map = new HashMap<>();
while (scanner.hasNext()) {
    String line = scanner.nextLine();
    int eq = line.indexOf('=');
    String key = line.substring(0, eq);
    String value = line.substring(eq + 1);
    if (value.startsWith(START)) {
        StringBuilder sb = new StringBuilder(value.substring(START.length()));
        while (!value.endsWith(END)) {
            value = scanner.nextLine();
            sb.append('\n').append(value);
        }
        value = sb.substring(0, sb.length() - END.length());
    }
    map.put(key, value);
}

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.printf("%s -> %s\n", entry.getKey(), entry.getValue());
}
janos
  • 120,954
  • 29
  • 226
  • 236
0

The following regex can find all your key/value pairs:

(?ms)^(\w+)=(?:start\((.*?)\)end|(.*?))$

The key will be in capture group 1, and the value will be in capture group 2 or 3.

Test

String input = "key1=1\r\n" +
               "key2=start(a\r\n" +
               "b\r\n" +
               "c=\r\n" +
               "d)end\r\n" +
               "key3=d=e=f\r\n" +
               "somekey=start(123)end\r\n" +
               "morekey=start(1\r\n" +
               "2)end\r\n" +
               "key=jj\r\n";

String regex = "(?ms)^(\\w+)=(?:start\\((.*?)\\)end|(.*?))$";

Map<String, String> map = new HashMap<>();
for (Matcher m = Pattern.compile(regex).matcher(input); m.find(); )
    map.put(m.group(1), (m.start(2) != -1 ? m.group(2) : m.group(3)));

for (Entry<String, String> e : map.entrySet())
    System.out.printf("%-7s -> %s%n", e.getKey(),
                      e.getValue().replaceAll("(\\R)", "$1           "));

Output

key1    -> 1
key2    -> a
           b
           c=
           d
key3    -> d=e=f
somekey -> 123
morekey -> 1
           2
key     -> jj
Andreas
  • 154,647
  • 11
  • 152
  • 247