Вкл. appendReplacement/Tail
Вам придется явно использовать appendReplacement
и appendTail
.К сожалению, вы должны использовать 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
См. Также
Другой пример: замена в верхнем регистре 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("<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
о недопустимой ссылке на группу (потому что $
не экранируется в строке заменыэто обратная ссылка сигил ).
Вкл. 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 раза всегда даст вам один и тот же результат ( см. Также на 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!!!
См. Также