DevRj DevRj - 3 years ago 128
Java Question

Split string to words after a given symbol in java

My string would be like :

String s = "args: val args1: val1 args2: val3 /*...argsn: valn*/";
///*...argsn: valn*/ means that the string may contain n number of args and vals


Where:
args os s word or a combination of words i already know
val can be a single word or a full text that may contain words and symbols like ":" or ","...
What i want to do is display for any given 'args' display it's 'val'

Here's what i tried :

public class Main {
public static void main(String[] args) {
String s = "arg1: val1 arg2: val2 arg3: va:l3";

String[] rawPairs = s.replace(": ", ":").split(" ");

Map<String, String> argsMap = Arrays.stream(rawPairs).collect(toMap(pair -> pair.substring(0, pair.indexOf(":")), pair -> pair.substring(pair.indexOf(":") + 1)));
System.out.println(argsMap.get("arg3"));
System.out.println(argsMap.get("arg5"));

}
}


this works if the 'val' is a single word but once it's a text i get this error for this input :

String s = "arg1: val1 arg2: val2 is a sentence arg3: va:l3";


Errors :

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1967)
at mainTest.lambda$main$0(mainTest.java:306)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at mainTest.main(mainTest.java:306)

sam sam
Answer Source

Try using Pattern & Matcher like below:

String s = "arg1 : val1 arg2 : val2 arg3 : va:l3";

if (s.contains("arg")) {

  Pattern pattern = Pattern.compile("arg1 :(.*?)arg2");
  Matcher matcher = pattern.matcher(s);
  while (matcher.find()) {
       System.out.println(matcher.group(1));                                
       String value = matcher.group(1);
       System.out.println(value);   
  }
}

The above code gets you all the characters between "arg1 :" and "arg2". Do as per your requirement.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download