Reputation: 6365
When writing a text editor with find and replace functionality the user has the ability to search multiple times and then replace. In Java the search part is quite easy:
Pattern pattern = Pattern.compile(userInput);
...
String line = ...
Matcher matcher = pattern.matcher(line);
int from = 0;
while (from < line.length() && matcher.find(from)) {
int start = matcher.start();
int length = matcher.end() - start;
// pseudo-code:
if (askUser()) {
return ...
}
from = start + 1;
}
But how to handle the replace of the n-th match? Matcher
has replaceAll
and replaceFirst
. The first obviously will not be suitable, but for the replaceFirst
the documentation says:
Replaces the first subsequence of the input sequence that matches the pattern with the given replacement string. This method first resets this matcher. It then scans the input sequence looking for a match of the pattern.
where the bold sentence makes me worry whether it would be suitable here. I'd need something to replace the current match with a certain pattern.
Upvotes: 4
Views: 104
Reputation: 31299
If you want to replace with the full Matcher.replaceFirst
syntax, which includes possible references to capture groups, you can look at the source of replaceFirst
. It calls two public methods in Matcher
: appendReplacement
and appendTail
. You can call them too without first resetting the matcher and without doing a find
call:
StringBuffer sb = new StringBuffer();
matcher.appendReplacement(sb, replacement);
matcher.appendTail(sb);
This results in a new Stringbuffer with the input string except that the current match is replaced by your replacement String (which can contain references to capture groups)
Upvotes: 1
Reputation: 274470
If you want to replace a specific match, call find()
multiple times and replace the matched portion using the start()
and end()
methods.
StringBuilder builder = new StringBuilder(stringToMatch);
Matcher m = Pattern.compile(yourRegex).matcher(stringToMatch);
for (int i = 0 ; i < n ; i++) { // n is the nth match you want to replace
m.find();
}
builder.replace(m.start(), m.end(), yourReplacement);
Upvotes: 6