2017-07-25 3 views
-1

My string wäre wie:Split String Worte nach einem bestimmten Symbol in Java

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

Wo: args os Wort oder eine Kombination von Wörtern i bereits val wissen kann ein einzelnes Wort oder eine sein Volltext, der Wörter und Symbole wie enthalten „:“ oder „“ ... Was ich tun möchte, ist Anzeige für jede gegebene ‚args‘ display es ist ‚val‘

Hier ist, was ich versucht:

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")); 

    } 
} 

funktioniert dies, wenn die ‚val‘ ein einzelnes Wort ist, aber wenn es ein Text ist bekomme ich diesen Fehler für diesen Eingang:

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

Fehler:

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) 
+0

Sie brauchen ein anderes Trennzeichen vielleicht ... etwas, das nicht in der Arg oder Val auftreten darf. – Lino

+1

müssten Sie wählen, welches Format die Zeichenfolge genau hätte. Sie haben 2 verschiedene Beispiele – XtremeBaumer

+1

noch nicht vollständig gewählt ... erste Zeichenfolge, die Sie zeigen, ist "String s =" args: val args1: val1 args2: val3/*.. .argsn: valn */";' dann zeigen Sie 'String s = "arg1: val1 arg2: val2 arg3: va: l3"; und als letztes zeigt man 'String s =" arg1: val1 arg2: val2 ist ein Satz arg3: va: l3 ";'. Das sind 3 völlig verschiedene Fälle. wähle 1 und wir könnten etwas ausarbeiten – XtremeBaumer

Antwort

1

Versuchen Muster mit & Matcher wie unten:

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); 
    } 
} 

Der obige Code bekommt man alle Zeichen zwischen "arg1 :" und "arg2" . Tun Sie gemäß Ihrer Anforderung.

+0

In der Tat funktioniert es für "args: val" nicht mein Fall, überprüfen Sie die Bearbeitung bitte – DevRj

+0

Hat nicht OP bitten, ArgN: val-Paare zu analysieren? Nicht arg1 und arg2 ... warum ist das upvoted? – CrazySabbath

+0

Es ist nur ein Beispiel, um Zeichen zwischen zwei anderen Zeichen in einem String zu erhalten. Es könnte hilfreich sein, wenn der oben angegebene Code nach Bedarf geloopt wird. – sam

4

Probieren Sie es mit einem regulären Ausdruck:

String s = "arg1 : val1 arg2 : val2 is a sentence arg3 : va:l3"; 
Map<String, String> argMap = new HashMap<String, String>(); 
Matcher argMatcher = Pattern.compile("arg\\d*\\s?:\\s.*?(?=(\\s+arg\\d|$))").matcher(s); 

while (argMatcher.find()) 
{ 
    String match = argMatcher.group(); 
    String[] pair = match.split("\\s\\:\\s"); 
    argMap.put(pair[0], pair[1]); 
} 

System.out.println(argMap); 

Er druckt:

{arg3=va:l3, arg2=val2 is a sentence, arg1=val1} 
+0

ich denke, OP will eine karte bestehend aus arg und seine val – Lino

+0

und leider wissen wir immer noch nicht auf welche string genau er will – XtremeBaumer

+0

Auch es gibt ein ' : 'auf den dritten Wert ausgegeben, die ich nicht glaube, was das OP will – DCON

2

Der Ausdruck, den Sie analysieren möchten, ist nicht eindeutig.

Zum Beispiel können Sie nicht unterscheiden food: bread score: 10, das könnte nach Ihrer Definition entweder bedeuten:

  • arg1:food, val1:bread und arg2:score, val2:10
  • arg1:food, val1:bread score: 10 (seit : kann Teil der seine Wert)

Solange es zweideutige Fälle wie diesen gibt, Sie wird nicht in der Lage sein, deine Schnur zuverlässig zu teilen.

Sie müssen eine bessere, zuverlässigere Darstellung der Daten finden, die Sie analysieren möchten.

Zum Beispiel können Sie Ihre Daten als JSON-String darstellen

{"arg1":"val1","arg2":"val2",...} 
1

Wie wir wissen immer noch nicht, was genau die Zeichenfolge wie folgt aussieht, werde ich zwei ziemlich ähnliche Lösungen geben:

String s = "arg1: val1 arg2: val2 arg3: va:l3"; 
Map<String, String> map = new LinkedHashMap<String, String>(); 
String[] splitted = s.split("arg\\d*:"); 
for (int i = 1; i < splitted.length; i++) { 
    map.put(String.valueOf("arg" + (i)), splitted[i].trim()); 
} 
System.out.println(map); 

für den Fall, dass der String enthält arg und

String s = "arg1: val1 arg2: val2 arg3: va:l3"; 
    Map<String, String> map = new LinkedHashMap<String, String>(); 
    String[] splitted = s.split("args\\d*:"); 
    for (int i = 1; i < splitted.length; i++) { 
     map.put(String.valueOf("arg" + (i)), splitted[i].trim()); 
    } 
    System.out.println(map); 

für den Fall, dass der String args enthält.Diese Lösung erfüllt auch die Daten in einer Karte Schlüssel und Wert für den Zugriff separat

1

Ein bisschen zu spät, aber hier ist der Code, der wirklich die Original-Zeichenkette in die folgenden analysiert:

arg1: val1 
arg2: val2 
arg3: 
va:l3 

nur ein bisschen ausgearbeitet

public static void main(String[] argv) { 
    String argStr = "arg1: val1 arg2: val2 arg3: va:l3"; 
    Pattern p = Pattern.compile("(^|\\s)(\\w+:)"); 
    Matcher m; 
    LinkedList<StringBuilder> argLst = new LinkedList<>(); 

    while ((m = p.matcher(argStr)).find()) { 
     if (m.start(1) > 0) 
      argLst.getLast().append(argStr.substring(0, m.start(1))); 
     if (!argLst.isEmpty()) 
      argLst.getLast().append(m.group(1)); 
     argLst.add(new StringBuilder(m.group(2))); 
     argStr = argStr.substring(m.end(2)); 
    } 
    if (!argStr.isEmpty() && !argLst.isEmpty()) 
     argLst.getLast().append(argStr); 


    for (StringBuilder sb: argLst) 
     System.out.println(sb.toString()); 
}