我有一个 ws.properties 文件,其中有一个名为 success.code 的属性,它让我可以选择选择哪些 HTTP 状态成功代码 (2xx),从默认的 200 开始,我希望服务器也将其视为“成功”。
思路是这样的:
- 如果我输入这样的值:
success.code=201,202, 203 (values separated by a comma)
负责提取这个值的代码部分应该立即明白这是三个独立的代码,提取它们中的每一个并将它们存储在列表或集合或....
这其实很简单:
private Set<String[]> getSuccessCodes(HashMap<String, String> codes){
Set<String[]> successCodes = new HashSet<>();
String value;
for (Map.Entry<String, String> entry : codes.entrySet()) {
value = entry.getValue();
if(!StringUtils.isEmpty(value))
successCodes.add(value.split("\\s*,\\s*"));
}
return successCodes;
}
- 这里有点复杂:
我也想添加这些选项:
success.code=[202, 220] (two values written between hooks and separated by a comma)
- [202, 220]:当值这样写的时候,我想让上面的方法明白,我想像第一种情况一样,提取、存储和返回202到220之间的所有值。
success.code=2**
- 这意味着所有以 2 开头的代码(从 201 到 299)都应该存储在一个集合或一个列表中,并通过该方法返回给我
success.code=[200, 205], 22*
- 这意味着我希望代码返回 200 到 205 之间的所有代码(所以 200、201、202、..、2005)加上从 220 到 220 的代码。
因此,根据我为成功代码输入的值,程序应该能够理解要做什么以及从中返回什么。
这可以实现吗?
提前致谢
最佳答案
如果您不介意再添加三个方法,这里是一种方法:
- 使用
"\\s*,\\s*(?![^\\[]*\\])"
在每个逗号处拆分值,除非在括号中 - 遍历结果数组并映射每个元素,检查它是否包含
[
或*
- 如果它包含
[
使用[x,y]
中的值生成一个IntStream.rangeClosed(x,y)
并映射它们到他们的字符串值 - 如果它包含
*
生成IntStream.rangeClosed(x00,x99)
通过将*
替换为0
和9
并将它们映射到它们的字符串值
类似于:
private static Set<String[]> getSuccessCodes(HashMap<String, String> codes){
Set<String[]> successCodes = new HashSet<>();
String value;
for (Map.Entry<String, String> entry : codes.entrySet()) {
value = entry.getValue();
if(!StringUtils.isEmpty(value))
successCodes.add(parse(value));
}
return successCodes;
}
public static String[] parse(String val) {
String[] parts = val.split("\\s*,\\s*(?![^\\[]*\\])");
return Arrays.stream(parts)
.map(e -> e.contains("[")? getRangeCodes(e): e.contains("*")? getWildCCodes(e): e)
.collect(Collectors.joining(",")).split("\\s*,\\s*");
}
private static String getRangeCodes(String e) {
e = e.substring(1, e.length()-1);
return IntStream.rangeClosed(Integer.parseInt(e.split("\\s*,\\s*")[0]), Integer.parseInt(e.split("\\s*,\\s*")[1]))
.mapToObj(i -> String.valueOf(i))
.collect(Collectors.joining(","));
}
private static String getWildCCodes(String e) {
return IntStream.rangeClosed(Integer.parseInt(e.replace('*', '0')), Integer.parseInt(e.replace('*', '9')))
.mapToObj(i -> String.valueOf(i))
.collect(Collectors.joining(","));
}
测试:
public static void main(String[] args) {
HashMap<String, String> codes = new HashMap<>();
codes.put("foo", "201, 202, 203");
codes.put("bar", "[202, 220]");
codes.put("baz", "2**");
codes.put("doo", "[200, 205], 22*");
codes.put("woo", "200, 201, 202, 203,[209, 214], 29*");
Set<String[]> set = getSuccessCodes(codes);
set.forEach(s -> {System.out.println(Arrays.toString(s));});
}
关于java - 从可以采用多种形式并从 Java 中的 .properties 文件加载的字符串中提取值的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58955196/