2017-07-25 97 views
-1
給定的符號後

我的字符串將是這樣的:分割字符串的話在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 

其中: ARGS OS話語或單詞的組合,我已經知道 VAL可以是單個單詞或全文可以包含文字和符號,如「:」或「」 ... 我想要做的是對於任何給定‘ARGS’顯示它的‘VAL’

這裏顯示的是我的嘗試:

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

    } 
} 

這個工程如果「VAL」是一個字,但一旦它是一個文本我得到這個錯誤此輸入:

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

錯誤:

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

您需要另一個分隔符,也許......一定不能發生在arg或val中。 – Lino

+1

你將不得不選擇字符串準確的格式。你給 – XtremeBaumer

+1

還沒有完全選擇2個不同的例子...你看第一個字符串是'一個String = 「ARGS:VAL args1:VAL1 args2:VAL3 /*...argsn:VALN * /」;'然後告訴你'字符串s =「arg1:val1 arg2:val2 arg3:va:l3」;'並且最後一次顯示'String s =「arg1:val1 arg2:val2是一個句子arg3:va:l3」;'。這些是3種完全不同的情況。選擇1,我們可以工作一些東西 – XtremeBaumer

回答

1

使用模式&匹配器像下面嘗試:

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

上面的代碼可以讓你所有"arg1 :""arg2"之間的字符。按照您的要求做。

+0

事實上它適用於「args:val」不是我的情況,請檢查編輯請 – DevRj

+0

沒有OP要求解析任何argN:val對嗎?不是arg1和arg2 ...爲什麼這是upvoted? – CrazySabbath

+0

它只是一個樣本來獲取字符串中兩個其他字符之間的字符。如果上面給出的代碼按照要求循環,這可能會有所幫助。 – sam

4

用正則表達式試試看:

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

它打印:

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

我覺得OP想要一個地圖由ARG和VAL – Lino

+0

和可悲的是,我們仍然不知道在哪個字符串正是他要同時經營 – XtremeBaumer

+0

,有一個' :'輸出的第三個值,我不認爲是OP要的 – DCON

2

您嘗試解析的表達式不明確。

例如,你不能區分food: bread score: 10,它按照自己的定義可能意味着兩種:

  • arg1:foodval1:breadarg2:scoreval2:10
  • arg1:foodval1:bread score: 10(因爲:可以部分值)

只要會出現模棱兩可的情況下,像這樣的,你將無法可靠地拆分您的字符串。

您需要找到一個更好,更可靠的想要解析的數據表示形式。

例如,你可以代表你的數據作爲JSON字符串

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

因爲我們仍然不知道到底該字符串的樣子,我給2個非常類似的解決方案:

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

該字符串包含arg

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

的情況下對於字符串包含args的情況。該解決方案還填充數據在地圖中來不及訪問鍵,分別

1

值了一點,但這裏是真正的解析原始的字符串爲以下代碼:

arg1: val1 
arg2: val2 
arg3: 
va:l3 

只是有點闡述

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