展开文本中的环境变量
问题内容:
我正在尝试编写一个函数来执行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;
}
使用上面的示例文本,matcher.matches()
返回false。但是,如果我的示例文本是${APPDATA}
可行的。
有人可以帮忙吗?
问题答案:
您不想使用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);
}