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

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来做到这一点。 这是一个片段( 另见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 

也可以看看

  • Java中的StringBuilder和StringBuffer
    • StringBuffersynchronized ,因此比StringBuilder
  • BugID 5066679: Matcher应该更多地使用Appendable
    • 如果获得批准,此增强请求将允许Matcher附加到任何可附加项

另一个例子: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(); } 

然后我们就可以了( 另见ideone.com ):

  Pattern p = Pattern.compile("<[^>]*>"); Matcher m = p.matcher(" bc  e  g <$$$> i "); System.out.println(replaceUppercase(4, m)); //  bc  e  g <$$$> i  // 1 2 3 4 

模式<[^>]*>只是一个匹配""的简单示例模式。

请注意,在此特定情况下, Matcher.quoteReplacement是必需的,否则附加"<$$$>"作为替换将触发关于非法组引用的IllegalArgumentException (因为替换字符串中的$ unescaped是反向引用sigil )。


replaceFirstreplaceAll

附件是replaceFirstreplaceAll (版本1.64 06/04/07)的java.util.regex.Matcher代码。 请注意,它使用基本相同的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在任何replaceFirst/All之前都是reset() 。 因此,简单地调用replaceFirst 3次总会得到相同的结果( 另见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 // ie THIS DOES NOT WORK!!! 

也可以看看

  • java.util.regex.Matcher源代码,OpenJDK版本