我正在尝试编写一个函数来在java中执行环境变量的替换.所以如果我有一个看起来像这样的字符串:
用户$ {USERNAME}的APPDATA路径为$ {APPDATA}.
我希望结果如下:
用户msmith的APPDATA路径是C:\ Users\msmith\AppData\Roaming.
到目前为止,我的破坏实现如下所示:
public static String expandEnvVars(String text) {
Map<String, String> envMap = System.getenv();
String pattern = "\\$\\{([A-Za-z0-9]+)\\}";
Pattern expr = Pattern.compile(pattern);
Matcher matcher = expr.matcher(text);
if (matcher.matches()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
String envValue = envMap.get(matcher.group(i).toUpperCase());
if (envValue == null) {
envValue = "";
} else {
envValue = envValue.replace("\\", "\\\\");
}
Pattern subexpr = Pattern.compile("\\$\\{" + matcher.group(i) + "\\}");
text = subexpr.matcher(text).replaceAll(envValue);
}
}
return text;
}
Run Code Online (Sandbox Code Playgroud)
使用上面的示例文本,matcher.matches()返回false.但是,如果我的示例文本,${APPDATA}它是否有效.
有人可以帮忙吗?
jjn*_*guy 15
你不想用matches().匹配将尝试匹配整个输入字符串.
尝试将整个区域与模式匹配.
你想要的是什么while(matcher.find()) {.这将匹配您的模式的每个实例.查看文档find().
在每个匹配中,group 0将是整个匹配的字符串(${appdata})并且group 1将是该appdata部分.
您的最终结果应如下所示:
String pattern = "\\$\\{([A-Za-z0-9]+)\\}";
Pattern expr = Pattern.compile(pattern);
Matcher matcher = expr.matcher(text);
while (matcher.find()) {
String envValue = envMap.get(matcher.group(1).toUpperCase());
if (envValue == null) {
envValue = "";
} else {
envValue = envValue.replace("\\", "\\\\");
}
Pattern subexpr = Pattern.compile(Pattern.quote(matcher.group(0)));
text = subexpr.matcher(text).replaceAll(envValue);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
以下替代方案无需求助于库即可达到预期效果:
expandEnvVars()将带有潜在占位符的文本作为参数${<key>}文本中出现的任何<value>,从而将占位符扩展到它们在环境中的当前值 private static Map<String, String> envMap = System.getenv();
public static String expandEnvVars(String text) {
for (Entry<String, String> entry : envMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
text = text.replaceAll("\\$\\{" + key + "\\}", value);
}
return text;
}
Run Code Online (Sandbox Code Playgroud)