2

I have the following text as in the code:

String input = "[xx] Guidance) Boundary: 123 | Total: 1010 | Steps Count test: 21 | initial value Count: 19";

I am trying to write the key value pair starting with Boundary to a LinkedHashmap, I used this Pattern matcher:

Matcher m = 
Pattern.compile("(\\S+):\\s(\\S*)(?:\\b(?!:)|$)").matcher(line1);

but it is not working and ignoring the space between the keys eg:Steps Count test? How can I tweak this to get it working?

BharathRao
  • 1,846
  • 1
  • 18
  • 28
user0007
  • 39
  • 5
  • I'm unclear what you are asking. What result, exactly, do you want? What input format(s) do you need to account for? What language are you using? Could you consider using some simple logic like: "Take everything starting from 'Boundary' until the end of the string, and split on '|' characters"? – Tom Lord Jan 30 '18 at 09:40
  • I am using Java, the regular expression I am using currently is not working on the input format I have provided. What would be the correct regex for "Boundary: 123 | Total: 1010 | Steps Count test: 21 | initial value Count: 19". So that I can the key value pairs to a map like this while (m.find()) { pairs.put(m.group(1), m.group(2)); } – user0007 Jan 30 '18 at 09:45
  • The correct answer is, like I said, probably [not to use a regex](https://stackoverflow.com/a/3481842/1954610). There are simpler ways to do this. – Tom Lord Jan 30 '18 at 09:49
  • Did my solution below work for you? – Wiktor Stribiżew Apr 22 '20 at 09:43

1 Answers1

1

You may easily get the key value pairs by splitting them with | (optionally enclosed with whitespace), iterate over the array and split with : (also optionally enclosed with whitespace).

See an example Java code:

Map<String, String> map = new HashMap<String, String>();
String test = "[xx] Guidance) Boundary: 123 | Total: 1010 | Steps Count test: 21 | initial value Count: 19";

String[] kvps = test.split("\\s*\\|\\s*"); // split on 'spaces|spaces'

for (int i = 0; i < kvps.length; i ++) {
    String[] kvp = kvps[i].split("\\s*:\\s*");
    map.put(kvp[0], kvp[1]);
}
// DEMO OUTPUT
for (String s : map.keySet()) {
    System.out.println(s + " => " + map.get(s));
}

Result:

initial value Count => 19
[xx] Guidance) Boundary => 123
Total => 1010
Steps Count test => 21

A matching regex solution will be probably too cumbersome and unsafe. E.g. you might try

([^:]+?)\s*:\s*([^\s|]+)

See the regex demo. It is as generic as possible, but relies on some assumptions: there can be no : before the : delimiter and the key cannot be empty, and the value cannot have whitespace and | char. If the key can be empty, replace ([^:]+?) with ([^:|]*?). If the value can contain whitespace, replace ([^\s|]+) with ([^|]+). Note you will need to trim() the values after matching them. See another regex demo.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563