我可以替换 Java 正则表达式中的组吗?

2022-08-31 08:44:41

我有这个代码,我想知道,如果我只能替换Java正则表达式中的组(不是所有模式)。法典:

 //...
 Pattern p = Pattern.compile("(\\d).*(\\d)");
    String input = "6 example input 4";
    Matcher m = p.matcher(input);
    if (m.find()) {

        //Now I want replace group one ( (\\d) ) with number 
       //and group two (too (\\d) ) with 1, but I don't know how.

    }

答案 1

使用(其中 n 是数字)引用 replaceFirst(...) 中捕获的子序列。我假设您要将第一组替换为文本字符串“number”,并将第二组替换为第一组的值。$n

Pattern p = Pattern.compile("(\\d)(.*)(\\d)");
String input = "6 example input 4";
Matcher m = p.matcher(input);
if (m.find()) {
    // replace first number with "number" and second number with the first
    String output = m.replaceFirst("number $3$1");  // number 46
}

考虑第二组而不是 。 是一个贪婪的匹配器,并且首先会消耗最后一个数字。然后,当匹配者意识到决赛没有任何匹配时,它必须回溯,然后才能匹配到最终数字。(\D+)(.*)*(\d)


答案 2

您可以使用 Matcher#start(group)Matcher#end(group) 来构建一个通用的替换方法:

public static String replaceGroup(String regex, String source, int groupToReplace, String replacement) {
    return replaceGroup(regex, source, groupToReplace, 1, replacement);
}

public static String replaceGroup(String regex, String source, int groupToReplace, int groupOccurrence, String replacement) {
    Matcher m = Pattern.compile(regex).matcher(source);
    for (int i = 0; i < groupOccurrence; i++)
        if (!m.find()) return source; // pattern not met, may also throw an exception here
    return new StringBuilder(source).replace(m.start(groupToReplace), m.end(groupToReplace), replacement).toString();
}

public static void main(String[] args) {
    // replace with "%" what was matched by group 1 
    // input: aaa123ccc
    // output: %123ccc
    System.out.println(replaceGroup("([a-z]+)([0-9]+)([a-z]+)", "aaa123ccc", 1, "%"));

    // replace with "!!!" what was matched the 4th time by the group 2
    // input: a1b2c3d4e5
    // output: a1b2c3d!!!e5
    System.out.println(replaceGroup("([a-z])(\\d)", "a1b2c3d4e5", 2, 4, "!!!"));
}

在此处查看在线演示