在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
你必须使用 appendReplacement
和 appendTail
明确地。不幸的是你必须使用 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
另见
- StringBuilder and StringBuffer in Java
-
StringBuffer
是synchronized
因此比StringBuilder
慢
-
- BugID 5066679:
Matcher
should make more use ofAppendable
- 如果获得批准,此增强请求将允许
Matcher
附加到任何Appendable
- 如果获得批准,此增强请求将允许
另一个例子: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 )。
关于 replaceFirst
和 replaceAll
附件是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/