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

时间:2010-08-10 11:18:31

标签: 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);
        }
    }
}

谢谢:)

2 个答案:

答案 0 :(得分:8)

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.MatcherreplaceFirst的{​​{1}}代码(版本1.64 06/04/07)。请注意,它使用的是基本相同的replaceAll逻辑:

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 3次总会得到相同的结果(see also on ideone.com):

replaceFirst

另见

答案 1 :(得分:0)

我认为使用StringUtils

代码

org.apache.commons.lang3.StringUtils.replace(content,"a","b",3);