我的字符串就像:
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 s word或我已经知道的单词组合 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"));
}
}
如果&#39; val&#39;是一个单词但是一旦它成为文本我就会得到这个输入的错误:
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 :(得分: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}
答案 1 :(得分:2)
您尝试解析的表达式不明确。
例如,您无法区分food: bread score: 10
,根据您的定义,arg1:food
可能意味着:
val1:bread
,arg2:score
和val2:10
,arg1:food
val1:bread score: 10
,:
(因为 {"arg1":"val1","arg2":"val2",...}
可以是价值的一部分)只要存在诸如此类的模糊情况,您将无法可靠地拆分字符串。
您需要找到一个更好,更可靠的代码来表示您要解析的数据。
例如,您可以将数据表示为json字符串
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {...}
答案 2 :(得分:1)
尝试使用Pattern&amp; Matcher如下:
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"
之间的所有字符。按照你的要求做。
答案 3 :(得分:1)
由于我们仍然不知道字符串的确切含义,我将给出两个非常相似的解决方案:
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}}的情况。此解决方案还会填充地图中的数据以分别访问密钥和值
答案 4 :(得分: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());
}