Java 为什么使用regex+;分组测试失败?

Java 为什么使用regex+;分组测试失败?,java,regex,Java,Regex,我正在使用正则表达式替换模板文件中的占位符 我有这个方法: public static String processTemplate(String template, Map<String, String> attributes) { Matcher m = PLACEHOLDER_PATTERN.matcher(template); String message = template; boolean matches = m.matches();

我正在使用正则表达式替换模板文件中的占位符

我有这个方法:

public static String processTemplate(String template, Map<String, String> attributes) {
    Matcher m = PLACEHOLDER_PATTERN.matcher(template);
    String message = template;
    boolean matches = m.matches();

    if (matches) {
        for (int i = 1; i < m.groupCount() + 1; i++) {
            message = message.replaceAll(m.group(i), attributes.get(m.group(i)));
        }
    }

    return message;
}
但这项测试失败了:

@Test
public void templates() {
    Map<String, String> attributes = new HashMap<>();
    attributes.put("${wobble}", "wobble");
    String result = processTemplate("wibble ${wobble}", attributes);
    assertEquals("wibble wobble", result);
}
@测试
公共void模板(){
Map attributes=newhashmap();
放置(“${wobble}”,“wobble”);
字符串结果=processTemplate(“wibble${wobble}”,属性);
资产质量(“wibble摆动”,结果);
}

我不知道为什么。“匹配”似乎返回false。

这是处理正则表达式的方法:

private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\$\\{.*?}");

public static String processTemplate(String template, Map<String, String> attributes) {
    Matcher m = PLACEHOLDER_PATTERN.matcher(template);

    StringBuffer sb = new StringBuffer();
    while (m.find()) {
       if (attributes.containsKey(m.group()))
           m.appendReplacement(sb, attributes.get(m.group()));
    }
    m.appendTail(sb);

    return sb.toString();
}
private static final Pattern占位符\u Pattern=Pattern.compile(\\$\\{.*?});
公共静态字符串processTemplate(字符串模板、映射属性){
匹配器m=占位符\模式匹配器(模板);
StringBuffer sb=新的StringBuffer();
while(m.find()){
if(attributes.containsKey(m.group()))
m、 appendReplacement(sb,attributes.get(m.group());
}
m、 (某人);
使某人返回字符串();
}
然后称之为:

Map<String, String> attributes = new HashMap<>();
attributes.put("${wobble}", "wobble");
String result = processTemplate("wibble ${wobble}", attributes);
//=> "wibble wobble"
Map attributes=newhashmap();
放置(“${wobble}”,“wobble”);
字符串结果=processTemplate(“wibble${wobble}”,属性);
//=>“wibble摆动”
变化如下:

  • 使用
    matcher.find()
    代替
    matcher.matches()
  • 使用
    matcher.appendReplacement()
    将每个替换项追加到缓冲区中
  • 最后调用
    matcher.appendTail()

  • 问题在于,正如文档所说,您使用的是:

    尝试根据图案匹配整个区域

    因此,当您传入
    “wibble${wobble}”
    时,匹配失败,因为
    “wibble”
    位未在正则表达式中计算


    您应该使用将查找下一个部分匹配项的
    Matcher.matches()

    测试只是一行,但产品代码是多行的。如果模式中没有
    ^
    $
    ,则
    模式。多行
    不会对您的模式产生任何影响。
    Pattern.DOTALL
    将强制
    匹配换行符,并且模式中有
    。模板“${wobble}”在它的行中没有任何换行符,但多行/换行符的内容是误导性的。我刚把它取下来。这与考试的通过或失败没有关系(我刚刚试过)。@WiktorStribiżew,\\$并不意味着结束?应该是“$”而不是“\\”?你完全正确,这就是我试图解决的问题。代码中还有一个我没有注意到的问题,那就是replaceAll也不起作用。这一点已被注意到,并通过公认的答案得到了解决。还有第二个问题,你也用这个解决方案解决了。事实证明,我的replaceAll也不会像编写的那样工作,但是您的解决方案很好地绕过了这个问题。再次感谢。
    Map<String, String> attributes = new HashMap<>();
    attributes.put("${wobble}", "wobble");
    String result = processTemplate("wibble ${wobble}", attributes);
    //=> "wibble wobble"