Java Regex替换为捕获组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Regex替换为捕获组相关的知识,希望对你有一定的参考价值。

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

例:

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

而且我想用$ 1替换所有出现次数乘以3。

编辑:

看起来,有些不对劲:(

如果我使用

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

它抛出IllegalStateException:找不到匹配项

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

工作正常,但我不能改变$ 1 :(

编辑:

现在,它的工作:)

答案

怎么样:

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

要获得第一场比赛,请使用#find()。之后,您可以使用#group(1)来引用第一个匹配,并将第一个匹配值乘以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());

您可能希望通过Matcher's documentation查看,其中详细介绍了此内容和更多内容。

另一答案

伯爵的回答给你解决方案,但我想我会添加导致你的IllegalStateException的问题。你没有先调用匹配操作(如group(1))就调用了find()。如果您只使用$1,则不需要这样做,因为replaceAll()是匹配操作。

另一答案

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

用法:

// 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);

实施(重新设计):

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("
	(%s) - %s", i, group(i)));
        return sb.toString();
    }
}
另一答案

Java 9提供了一个接受替换功能的Matcher.replaceAll()

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

以上是关于Java Regex替换为捕获组的主要内容,如果未能解决你的问题,请参考以下文章

java 字符串替换

有没有办法让 Regex.Match 只提供预期的捕获组?

从 Grep RegEx 中捕获组

python regex 使用捕获组来定义另一个组长度

如何仅获取给定的捕获组 <regex> c++

雪花:REGEXP 替换为捕获组的大写