Java 正则表达式替换为捕获组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1277157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 07:43:08  来源:igfitidea点击:

Java Regex Replace with Capturing Group

javaregex

提问by user

Is there any way to replace a regexp with modified content of capture group?

有没有办法用捕获组的修改内容替换正则表达式?

Example:

例子:

Pattern regex = Pattern.compile("(\d{1,2})");
Matcher regexMatcher = regex.matcher(text);
resultString = regexMatcher.replaceAll(""); // *3 ??

And I'd like to replace all occurrence with $1 multiplied by 3.

我想用 $1 乘以 3 来替换所有出现的情况。

edit:

编辑:

Looks like, something's wrong :(

好像出了点问题:(

If I use

如果我使用

Pattern regex = Pattern.compile("(\d{1,2})");
Matcher regexMatcher = regex.matcher("12 54 1 65");
try {
    String resultString = regexMatcher.replaceAll(regexMatcher.group(1));
} catch (Exception e) {
    e.printStackTrace();
}

It throws an IllegalStateException: No match found

它抛出一个 IllegalStateException: No match found

But

Pattern regex = Pattern.compile("(\d{1,2})");
Matcher regexMatcher = regex.matcher("12 54 1 65");
try {
    String resultString = regexMatcher.replaceAll("");
} catch (Exception e) {
    e.printStackTrace();
}

works fine, but I can't change the $1 :(

工作正常,但我无法更改 $1 :(

edit:

编辑:

Now, it's working :)

现在,它正在工作:)

采纳答案by earl

How about:

怎么样:

if (regexMatcher.find()) {
    resultString = regexMatcher.replaceAll(
            String.valueOf(3 * Integer.parseInt(regexMatcher.group(1))));
}

To get the first match, use #find(). After that, you can use #group(1)to refer to this first match, and replace all matches by the first maches value multiplied by 3.

要获得第一场比赛,请使用#find(). 之后,您可以使用#group(1)引用此第一个匹配项,并将所有匹配项替换为第一个 maches 值乘以 3。

And in case you want to replace each match with that match's value multiplied by 3:

如果您想用该匹配的值乘以 3 替换每个匹配:

    Pattern p = Pattern.compile("(\d{1,2})");
    Matcher m = p.matcher("12 54 1 65");
    StringBuffer s = new StringBuffer();
    while (m.find())
        m.appendReplacement(s, String.valueOf(3 * Integer.parseInt(m.group(1))));
    System.out.println(s.toString());

You may want to look through Matcher's documentation, where this and a lot more stuff is covered in detail.

您可能需要查看Matcher的文档,其中详细介绍了这一点以及更多内容。

回答by Draemon

earl's answer gives you the solution, but I thought I'd add what the problem is that's causing your IllegalStateException. You're calling group(1)without having first called a matching operation (such as find()). This isn't needed if you're just using $1since the replaceAll()is the matching operation.

厄尔的回答为您提供了解决方案,但我想我会添加导致您的IllegalStateException. 您在group(1)未首先调用匹配操作(例如find())的情况下调用。如果您只是使用$1replaceAll()则不需要,因为是匹配操作。

回答by Mykhaylo Adamovych

Source: java-implementation-of-rubys-gsub

来源:java-implementation-of-rubys-gsub

Usage:

用法:

// Rewrite an ancient unit of length in SI units.
String result = new Rewriter("([0-9]+(\.[0-9]+)?)[- ]?(inch(es)?)") {
    public String replacement() {
        float inches = Float.parseFloat(group(1));
        return Float.toString(2.54f * inches) + " cm";
    }
}.rewrite("a 17 inch display");
System.out.println(result);

// The "Searching and Replacing with Non-Constant Values Using a
// Regular Expression" example from the Java Almanac.
result = new Rewriter("([a-zA-Z]+[0-9]+)") {
    public String replacement() {
        return group(1).toUpperCase();
    }
}.rewrite("ab12 cd efg34");
System.out.println(result);

Implementation (redesigned):

实现(重新设计):

import static java.lang.String.format;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class Rewriter {
    private Pattern pattern;
    private Matcher matcher;

    public Rewriter(String regularExpression) {
        this.pattern = Pattern.compile(regularExpression);
    }

    public String group(int i) {
        return matcher.group(i);
    }

    public abstract String replacement() throws Exception;

    public String rewrite(CharSequence original) {
        return rewrite(original, new StringBuffer(original.length())).toString();
    }

    public StringBuffer rewrite(CharSequence original, StringBuffer destination) {
        try {
            this.matcher = pattern.matcher(original);
            while (matcher.find()) {
                matcher.appendReplacement(destination, "");
                destination.append(replacement());
            }
            matcher.appendTail(destination);
            return destination;
        } catch (Exception e) {
            throw new RuntimeException("Cannot rewrite " + toString(), e);
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(pattern.pattern());
        for (int i = 0; i <= matcher.groupCount(); i++)
            sb.append(format("\n\t(%s) - %s", i, group(i)));
        return sb.toString();
    }
}

回答by shmosel

Java 9 offers a Matcher.replaceAll()that accepts a replacement function:

Java 9 提供了一个Matcher.replaceAll()接受替换函数的方法:

resultString = regexMatcher.replaceAll(
        m -> String.valueOf(Integer.parseInt(m.group()) * 3));