Solution with Pattern
You could also change the String.replace method that uses the literal interpretation of characters to replace only the first occurrence of the target character sequence:
/**
* Replaces the first subsequence of the <tt>source</tt> character sequence
* that matches the literal target sequence with the specified literal
* replacement sequence.
*
* @param source source sequence on which the replacement is made
* @param target the sequence of char values to be replaced
* @param replacement the replacement sequence of char values
* @return the resulting string
*/
private static String replaceFirst1(CharSequence source, CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
source).replaceFirst(Matcher.quoteReplacement(replacement.toString()));
}
From the documentation of Pattern.LITERAL:
When this flag is specified then the input string that specifies the pattern is treated as a sequence of literal characters. Metacharacters or escape sequences in the input sequence will be given no special meaning.
Solution without Pattern
The other and more efficient way, of course, is to use Alex Martelli's hint to produce the following functionality:
/**
* Replaces the first subsequence of the <tt>source</tt> string that matches
* the literal target string with the specified literal replacement string.
*
* @param source source string on which the replacement is made
* @param target the string to be replaced
* @param replacement the replacement string
* @return the resulting string
*/
private static String replaceFirst2(String source, String target, String replacement) {
int index = source.indexOf(target);
if (index == -1) {
return source;
}
return source.substring(0, index)
.concat(replacement)
.concat(source.substring(index+target.length()));
}
Time measurement
Based on 10 runs, the replaceFirst2 method executes about 5 times faster than the replaceFirst1 method. I have put both of these methods in a loop with 100.000 repeats and got the following results, in milliseconds:
Method Results (in ms) Average
replaceFirst1: 220 187 249 186 199 211 172 199 281 199 | 210
replaceFirst2: 40 39 58 45 48 40 42 42 43 59 | 45