java - 在 matcher.replace 方法中,如何限制替换次数?

标签 java regex

matcher.replace方法中,只有: replaceFirst()replaceAll() 两个方法

我想限制替换3次,怎么办?

例子:

String content="aaaaaaaaaa";

我想要得到的结果是:"bbbaaaaaaa"

我的代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class T1 {
    public static void main(String[] args) {
        String content="aaaaaaaaaa";
        Pattern pattern = Pattern.compile("a");

        Matcher m=pattern.matcher(content);
        if(m.find()){
            String result=m.replaceFirst("b");
            System.out.println(result);
        }
    }
}

谢谢:)

最佳答案

关于 appendReplacement/Tail

你必须使用 appendReplacementappendTail明确地。不幸的是你必须使用 StringBuffer去做这个。这是一个片段(see also in ideone.com):

    String content="aaaaaaaaaa";
    Pattern pattern = Pattern.compile("a");
    Matcher m = pattern.matcher(content);

    StringBuffer sb = new StringBuffer();
    final int N = 3;
    for (int i = 0; i < N; i++) {
      if (m.find()) {
         m.appendReplacement(sb, "b");
      } else {
         break;
      }
    }
    m.appendTail(sb);
    System.out.println(sb); // bbbaaaaaaa

另见


另一个例子:N次大写替换

这是另一个例子,说明了 appendReplacement/Tail 是如何工作的。与 replaceFirst/replaceAll 相比,您可以更好地控制更换:

// replaces up to N times with uppercase of matched text
static String replaceUppercase(int N, Matcher m) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < N; i++) {
        if (m.find()) {
            m.appendReplacement(
                sb,
                Matcher.quoteReplacement(m.group().toUpperCase())
            );
        } else {
            break;
        }
    }
    m.appendTail(sb);
    return sb.toString();
}

然后我们可以有 ( see also on ideone.com ):

    Pattern p = Pattern.compile("<[^>]*>");
    Matcher m = p.matcher("<a> b c <ddd> e <ff> g <$$$> i <jjj>");

    System.out.println(replaceUppercase(4, m));
    // <A> b c <DDD> e <FF> g <$$$> i <jjj>
    //  1        2       3      4

图案 <[^>]*>只是一个匹配 "<tags like this>" 的简单示例模式.

请注意 Matcher.quoteReplacement 在这种特殊情况下是必要的,否则附加 "<$$$>"因为替换会触发 IllegalArgumentException关于非法组引用(因为 $ 在替换字符串中未转义是反向引用 sigil )。


关于 replaceFirstreplaceAll

附件是java.util.regex.Matcher replaceFirst 的代码和 replaceAll (版本 1.64 06/04/07)。请注意,它是使用基本相同的 appendReplacement/Tail 完成的。逻辑:

// Excerpt from  @(#)Matcher.java   1.64 06/04/07

public String replaceFirst(String replacement) {
    if (replacement == null)
        throw new NullPointerException("replacement");
    StringBuffer sb = new StringBuffer();
    reset(); // !!!!
    if (find())
        appendReplacement(sb, replacement);
    appendTail(sb);
    return sb.toString();
}

public String replaceAll(String replacement) {
    reset(); // !!!!
    boolean result = find();
    if (result) {
        StringBuffer sb = new StringBuffer();
        do {
            appendReplacement(sb, replacement);
            result = find();
        } while (result);
        appendTail(sb);
        return sb.toString();
    }
    return text.toString();
}

请注意 Matcher reset() 在任何 replaceFirst/All 之前.因此,只需调用 replaceFirst 3 次总能得到相同的结果 ( see also on ideone.com ):

        String content="aaaaaaaaaa";
        Pattern pattern = Pattern.compile("a");

        Matcher m = pattern.matcher(content);

        String result;

        result = m.replaceFirst("b"); // once!
        result = m.replaceFirst("b"); // twice!
        result = m.replaceFirst("b"); // one more for "good" measure!

        System.out.println(result);
        // baaaaaaaaa
        // i.e. THIS DOES NOT WORK!!!

另见

关于java - 在 matcher.replace 方法中,如何限制替换次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3448330/

相关文章:

Swing组件和jdk版本问题

java - setOnMouseEntered 不适用于 ListView 中的 ImageView

c# - 测试所有形式的邮政信箱

php - 正则表达式匹配golang sql dsn

java - 如何使用正则表达式获取第一个匹配字符串

regex - 使用 awk 仅打印第 n 个匹配项

java - 将图像保存到我的图库中

java - Maven 无法使用 Eclipse 解决 Jacob 依赖关系

java - 太多的 Maven 依赖

java - 正则表达式将表达式与一定数量/模式的斜杠相匹配