如果我有一个父字符串(我们称之为output
),其中包含一个变量赋值列表,如此...
status.availability-state available
status.enabled-state enabled
status.status-reason The pool is available
我想在给定变量名称的情况下提取该列表中每个变量的值,即status.availability-state
,status.enabled-state
和status.status-reason
之后的空格后面的子字符串,这样我最后得到三个不同的变量赋值,使得以下每个字符串比较都成立......
String availability = output.substring(TODO);
String enabled = output.substring(TODO);
String reason = output.substring(TODO);
availability.equals("available");
enabled.equals("enabled");
reason.equals("The pool is available");
最简单的方法是什么?我应该使用substring
吗?
答案 0 :(得分:2)
这有点棘手,因为您需要将值分配给特定变量 - 您不能只在Java中拥有变量键的映射。
我会考虑用开关来做这件事:
for (String line : output.split('\n')) {
String[] frags = line.split(' ', 2); // Split the line in 2 at the space.
switch (frags[0]) { // This is the "key" of the variable.
case "status.availability-state":
availability = frags[1]; // This assigns the "value" to the relevant variable.
break;
case "status.enabled-state":
enabled = frags[1];
break;
// ... etc
}
}
它不是很漂亮,但你没有太多的选择。
答案 1 :(得分:2)
这里似乎有两个问题 - 如何解析字符串,以及如何按名称分配变量。
一次解决一个字符串解析:
String.split()
或StringTokenizer
是两个选项。name: status.availability-state, value: available
。接下来,您要求根据参数名称以编程方式分配变量。
在运行时没有合法的方法来查看变量的名称(好的,Java 8反射有方法,但不应该在没有充分理由的情况下使用它)。
因此,您可以做的最好的事情是使用switch
或if
声明:
switch(name) {
case status.availability-state:
availability = value;
break;
... etc.
}
但是,无论何时使用switch
或if
,您都应该考虑是否有更好的方法。
是否有任何理由无法将这些变量转换为Map
条目?
configMap.add(name,value);
然后阅读:
doSomethingWith(configMap.get("status.availability");
这就是地图的用途。使用它们。
这与使用名为person1
,person2
,person3
的变量的新手错误类似,而不是使用数组。最终他们会问“我如何从25号到变量person25
?” - 答案是,你不能,但数组或列表使它变得容易。 people[number]
或people.get(number)
答案 2 :(得分:1)
有效的替代方法是将字符串拆分为\n
并添加到Map
。例如:
String properties = "status.availability-state available\nstatus.enabled-state enabled\nstatus.status-reason The pool is available";
Map<String, String> map = Arrays.stream(properties.split("\n"))
.collect(Collectors.toMap(s -> s.split(" ")[0], s -> s.split(" ", 2)[1]));
System.out.println(map.get("status.status-reason"));
应输出The pool is available
答案 3 :(得分:0)
此循环将匹配并提取变量,然后您可以根据需要分配它们:
Pattern regex = Pattern.compile("status\\.(.*?)-.*? ([a-z]+)");
Matcher matcher = regex.matcher(output);
while (matcher.find()) {
System.out.println(matcher.group(1) + "=" + matcher.group(2));
}
status\\.
匹配“状态。”
(.*?)
匹配任何字符序列,但不贪婪,并捕获它们
-.*
匹配破折号,任何字符,空格
([a-z]+)
匹配任何小写字母字符串,并捕获它们
答案 4 :(得分:0)
这是一种方法:
Map<String, String> properties = getProperties(propertiesString);
availability = properties.get("availability-state");
enabled = properties.get("enabled-state");
reason = properties.get("status-reason");
// ...
public void getProperties(String input) {
Map<String, String> properties = new HashMap<>();
String[] lines = output.split("\n");
for (String line : lines) {
String[] parts = line.split(" ");
int keyStartIndex = parts[0].indexOf(".") + 1;
int spaceIndex = parts[1].indexOf(" ");
string key = parts[0].substring(keyStartIndex, spaceIndex);
properties.put(key, parts[1]);
}
return properties;
}
就设置这些值的代码而言,这似乎更直接,因为每个值都设置为映射中的值,而不是迭代某些字符串列表并查看它是否包含一个特定的价值,并根据它做不同的事情。
这是为主要用例设计的,即字符串是在运行时在内存中创建的。如果在外部文件中创建属性,则此代码仍然有效(在内存中创建所需的String之后),但使用Properties
文件或Scanner
可能更好。 }。