在Java中使用。*的Regexp分组和replaceAll复制替换

时间:2011-02-17 12:42:40

标签: java regex

我在Java中使用Rexexp时遇到了问题。示例代码写出ABC_012_suffix_suffix,我希望它输出ABC_012_suffix

    Pattern rexexp  = Pattern.compile("(.*)");
    Matcher matcher = rexexp.matcher("ABC_012");
    String  result  = matcher.replaceAll("$1_suffix");

    System.out.println(result);

我理解replaceAll会替换所有匹配的组,问题是为什么这个regexp组(.*)在我的字符串ABC_012中匹配两次?

3 个答案:

答案 0 :(得分:6)

Pattern regexp  = Pattern.compile(".*");
Matcher matcher = regexp.matcher("ABC_012");
matcher.matches();
System.out.println(matcher.group(0));
System.out.println(matcher.replaceAll("$0_suffix"));

这里也是如此,输出是:

ABC_012
ABC_012_suffix_suffix

原因隐藏在replaceAll方法中:它尝试find与模式匹配的所有子序列:

while (matcher.find()) {
  System.out.printf("Start: %s, End: %s%n", matcher.start(), matcher.end());
}

这将导致:

Start: 0, End: 7
Start: 7, End: 7

所以,我们第一个惊喜,匹配器找到两个子序列,"ABC_012"和另一个""。它将"_suffix"附加到其中:

"ABC_012" + "_suffix" + "" + "_suffix"

答案 1 :(得分:5)

可能.*为您提供“完全匹配”,然后将匹配减少为“空匹配”(但仍匹配)。请改为(.+)(^.*$)。两者都按预期工作。

在regexinfo星的定义如下:

  

*(星号) - 重复前一项零次或多次。贪婪,因此在尝试使用前一项目的匹配较少的排列之前,将匹配尽可能多的项目,直到前一项目根本不匹配为止。

答案 2 :(得分:3)

如果您只想在输入中添加“_suffix”,为什么不这样做:

String result = "ABC_012" + "_suffix";