在Java字符串中搜索和替换格式化属性

在Java字符串中搜索和替换格式化属性,java,regex,string,Java,Regex,String,我将得到包含格式化“属性”的字符串;也就是说,封装在标准“${”和“}”标记中的字符串: “这是${string}的${example},我可能是${given}。” 我还将有一个HashMap,其中包含每个可能的格式化属性的替换: HashMap Keys HashMapValues =========================================== bacon eggs ham s

我将得到包含格式化“属性”的字符串;也就是说,封装在标准“${”和“}”标记中的字符串:

“这是${string}的${example},我可能是${given}。”

我还将有一个
HashMap
,其中包含每个可能的格式化属性的替换:

HashMap Keys           HashMapValues
===========================================
bacon                  eggs
ham                    salads
因此,给定以下字符串:

“我喜欢吃熏肉和火腿。”

我可以将其发送到Java方法,该方法将其转换为:

“我喜欢吃鸡蛋和沙拉。”

以下是我最好的尝试:

System.out.println("Starting...");

String regex = "$\\{*\\}";
Map<String,String> map = new HashMap<String, String>();
map.put("bacon", "eggs");
map.put("ham", "salads");

String sampleString = "I like ${bacon} and ${ham}.";

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(sampleString);
while(matcher.find()) {
    System.out.println("Found " + matcher.group());

    // Strip leading "${" and trailing "}" off.
    String property = matcher.group();

    if(property.startsWith("${"))
        property = property.substring(2);
    if(property.endsWith("}"))
        property = property.substring(0, property.length() - 1);

    System.out.println("Before being replaced, property is: " + property);

    if(map.containsKey(property))
        property = map.get(property);

    // Now, not sure how to locate the original property ("${bacon}", etc.)
    // inside the sampleString so that I can replace "${bacon}" with
    // "eggs".
}

System.out.println("Ending...");
System.out.println(“开始…”);
字符串regex=“$\\{*\}”;
Map Map=newhashmap();
地图。放(“培根”、“鸡蛋”);
地图。摆放(“火腿”、“沙拉”);
String sampleString=“我喜欢${bacon}和${ham}。”;
Pattern=Pattern.compile(regex);
Matcher Matcher=pattern.Matcher(sampleString);
while(matcher.find()){
System.out.println(“Found”+matcher.group());
//去掉前面的“${”和后面的“}”。
字符串属性=matcher.group();
if(property.startsWith(“${”))
property=property.substring(2);
if(property.endsWith(“}”))
property=property.substring(0,property.length()-1);
System.out.println(“替换前,属性为:“+属性”);
if(地图容器(财产))
property=map.get(属性);
//现在,不确定如何定位原始属性(${bacon}),等等)
//在sampleString中,这样我就可以将“${bacon}”替换为
//“鸡蛋”。
}
System.out.println(“结束…”);
当我执行此操作时,没有错误,但只看到“开始…”和“结束…”输出。这告诉我我的正则表达式不正确,因此
匹配器
无法匹配任何属性

所以我的第一个问题是:这个正则表达式应该是什么

一旦我过了这一关,我就不知道在我将“${bacon}”更改为“鸡蛋”后如何执行字符串替换。有什么想法吗?提前谢谢

改用这个:

String regex = "\\$\\{([^}]*)\\}";
然后,仅获取捕获组1内
${
}
之间的内容

请注意,
$
在模式中有一个特殊的含义:字符串的结尾

因此,必须将其转义为文字(如花括号)。

为什么不使用.properties文件?,这样您可以从该文件获取所有消息,并且可以与代码分离,例如(file example.properties):

然后在您的课堂上加载您的捆绑包并按如下方式使用:

ResourceBundle bundle = ResourceBundle.getBundle("example.properties", Locale.getDefault());
MessageFormat.format(bundle.getString('message1'), "param0", "param1"); // This gonna be your formatted String "This is a param0 with format markers on it param1"
您可以使用MessageFormat(是一个java.util库)而不使用bundle(直接使用字符串),但同样,拥有bundle可以让代码更清晰(并使国际化更容易)

更好地使用from。它也可以替代系统道具

自从commons lang 3.6以来,StrSubstitutor一直被弃用,取而代之的是StringSubstitutor。例如:

import org.apache.commons.text.StringSubstitutor;

Properties props = new Properties();
props.setProperty("bacon", "eggs");
props.setProperty("ham", "salads");
String sampleString = "I like ${bacon} and ${ham}.";
String replaced = StringSubstitutor.replace(sampleString, props);

为了完成这项工作,这里有一个可行的解决方案:

static final Pattern EXPRESSION_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");

/**
 * Replace ${properties} in an expression
 * @param expression expression string
 * @param properties property map
 * @return resolved expression string
 */
static String resolveExpression(String expression, Map<String, String> properties) {
    StringBuilder result = new StringBuilder(expression.length());
    int i = 0;
    Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
    while(matcher.find()) {
        // Strip leading "${" and trailing "}" off.
        result.append(expression.substring(i, matcher.start()));
        String property = matcher.group();
        property = property.substring(2, property.length() - 1);
        if(properties.containsKey(property)) {
            //look up property and replace
            property = properties.get(property);
        } else {
            //property not found, don't replace
            property = matcher.group();
        }
        result.append(property);
        i = matcher.end();
    }
    result.append(expression.substring(i));
    return result.toString();
}
静态最终模式表达式\u Pattern=Pattern.compile(\\$\\{([^}]*)\});
/**
*替换表达式中的${properties}
*@param表达式字符串
*@param属性属性映射
*@return解析表达式字符串
*/
静态字符串解析表达式(字符串表达式、映射属性){
StringBuilder结果=新的StringBuilder(expression.length());
int i=0;
Matcher Matcher=EXPRESSION\u PATTERN.Matcher(表达式);
while(matcher.find()){
//去掉前面的“${”和后面的“}”。
append(expression.substring(i,matcher.start());
字符串属性=matcher.group();
property=property.substring(2,property.length()-1);
if(properties.containsKey(property)){
//查找属性并替换
property=properties.get(属性);
}否则{
//未找到属性,请不要替换
property=matcher.group();
}
结果.追加(属性);
i=matcher.end();
}
expression.substring(i));
返回result.toString();
}

尝试用正则表达式解决这个问题(如果可能的话…)是一个学术练习,“在现实世界中”你应该使用一个引擎,例如,这是最简单的答案。使用其他人测试过的库。
static final Pattern EXPRESSION_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");

/**
 * Replace ${properties} in an expression
 * @param expression expression string
 * @param properties property map
 * @return resolved expression string
 */
static String resolveExpression(String expression, Map<String, String> properties) {
    StringBuilder result = new StringBuilder(expression.length());
    int i = 0;
    Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
    while(matcher.find()) {
        // Strip leading "${" and trailing "}" off.
        result.append(expression.substring(i, matcher.start()));
        String property = matcher.group();
        property = property.substring(2, property.length() - 1);
        if(properties.containsKey(property)) {
            //look up property and replace
            property = properties.get(property);
        } else {
            //property not found, don't replace
            property = matcher.group();
        }
        result.append(property);
        i = matcher.end();
    }
    result.append(expression.substring(i));
    return result.toString();
}