21

我想用匹配的编号/索引替换匹配。

java regex 风格有没有办法知道当前匹配是哪个匹配号,所以我可以使用String.replaceAll(regex, replacement)

示例:替换[A-Z]为自身及其索引:

Input:  fooXbarYfooZ
Output: fooX1barY2fooZ3

即,这个电话:

"fooXbarXfooX".replaceAll("[A-Z]", "$0<some reference to the match count>");

应该返回"fooX1barY2fooZ3"


注意:我正在寻找可以执行此操作的替换字符串(如果存在)。


请不要提供涉及循环或类似代码的答案。


编辑:

我会接受最优雅的有效答案(即使它使用循环)。当前的答案没有
真正起作用。

4

4 回答 4

6

需要对输入字符串进行迭代,因此以一种或另一种方式循环是不可避免的。标准 API 没有实现实现该循环的方法,因此该循环要么必须在客户端代码中,要么在第三方库中。


顺便说一句,代码如下所示:

public abstract class MatchReplacer {

    private final Pattern pattern;

    public MatchReplacer(Pattern pattern) {
        this.pattern = pattern;
    }

    public abstract String replacement(MatchResult matchResult);

    public String replace(String input) {

        Matcher m = pattern.matcher(input);

        StringBuffer sb = new StringBuffer();

        while (m.find())
            m.appendReplacement(sb, replacement(m.toMatchResult()));

        m.appendTail(sb);

        return sb.toString();
    }
}

用法:

public static void main(String... args) {
    MatchReplacer replacer = new MatchReplacer(Pattern.compile("[A-Z]")) {
        int i = 1;
        @Override public String replacement(MatchResult m) { 
            return "$0" + i++;
        }
    };
    System.out.println(replacer.replace("fooXbarXfooX"));
}

输出:

fooX1barX2fooX3
于 2012-06-05T06:06:16.723 回答
4

Java regex 不支持对匹配计数的引用,所以这是不可能的。

于 2012-12-21T18:45:42.423 回答
3

没有Java中的循环是不可能的......

于 2012-06-05T06:14:10.760 回答
3

好吧,我认为在 Java 中没有任何循环是不可能的。

String x = "fooXbarXfooX";
        int count = 0;
        while(x.contains("X"))
        x = x.replaceFirst("X", Integer.toString(count++));
        System.out.println(x);
于 2012-06-05T06:16:20.410 回答