Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex replace with the count of the match

Tags:

I would like to replace a match with the number/index of the match.

Is there way in java regex flavour to know which match number the current match is, so I can use String.replaceAll(regex, replacement)?

Example: Replace [A-Z] with itself and its index:

Input:  fooXbarYfooZ
Output: fooX1barY2fooZ3

ie, this call:

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

should return "fooX1barY2fooZ3"


Note: I'm looking a replacement String that can do this, if one exists.


Please do not provide answers involving loops or similar code.


Edited:

I'll accept the most elegant answer that works (even if it uses a loop). No current answers
actually work.

like image 780
Bohemian Avatar asked Jun 05 '12 05:06

Bohemian


2 Answers

Iterating over the input string is required so looping one way or the other is inevitable. The standard API does not implement a method implementing that loop so the loop either have to be in client code or in a third party library.


Here is how the code would look like btw:

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();
    }
}

Usage:

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"));
}

Output:

fooX1barX2fooX3
like image 136
dacwe Avatar answered Oct 05 '22 07:10

dacwe


Java regex does not support a reference to the count of the match, so it is impossible.

like image 43
Bohemian Avatar answered Oct 05 '22 08:10

Bohemian