Reputation: 17732
I've looked in the Java API and some common 3rd party libraries but I'm unable to find a suitable method that will do what String.replaceAll does, except for StringBuilder.
I know that with a little work, it can be done for StringBuffer, but I don't want to go down this road because StringBuffer is slower.
Does anyone know of any 3rd party utilies, or if there is a quick piece of code to implement this functionality?
Upvotes: 17
Views: 22389
Reputation: 7576
I don't want to go down this road because StringBuffer is slower.
True, but with the usual premature optimization caveat, and more importantly, modern JVMs use escape analysis to remove the StringBuffer/Vector/HashTable locks in certain cases, so once that optimization happens, the performance will be roughly the same.
Upvotes: 3
Reputation: 11041
Regex does not modify a mutable CharSequence
internally. Regex parses a CharSequence
to return a String
, where String
is the result. StringBuffer
is an exception as there is special handling - as for StringBuilder
being CharSequence
, you have to modify it with a match result.
What you can do instead:
// Class
private static final Pattern MY_PATTERN = Pattern.compile("my|regex");
{ // Method
StringBuilder builder;
// ...
Matcher m = MY_PATTERN.matcher(builder);
builder.replace(0, builder.length(), m.replaceAll("<b>$0</b>"));
}
Upvotes: 3
Reputation: 44259
String.replaceAll
is just a convenience method for Matcher.replaceAll
. Matcher
is the "actual" way to use regex in Java and is allows for a lot more sophisticated use cases.
Moreover, anything that can be done with regex methods on String
can be done with similar methods on a Matcher
. The beauty is, that Matcher
s work with more than just String
s: Matcher
s can be obtained for any CharSequence
(an interface, which is implemented by StringBuilder
, StringBuffer
, String
and CharBuffer
). So you can simply do:
import java.util.regex.*;
...
StringBuilder sb = new StringBuilder();
sb.append("This works with StringBuffers");
Pattern p = Pattern.compile("\\Buffer\\B");
Matcher m = p.matcher(sb);
System.out.println(m.replaceAll("uilder"));
Will output This works with StringBuilders
.
Upvotes: 13
Reputation: 21718
Apache Harmony Matcher source code seems fully reworkable to be used with StringBuilder
instead of the currently used StringBuffer
, just move to the different package. It seems not dragging a lot of dependences with it. Apache license that is at the start of the file may not be bad even for commercial project.
GNU Classpath code can also be reused but the license is more difficult there (you need to publish your changed version of the Matcher but probably not the rest of your code). Same about the original Sun's implementation that can be found here in the OpenJDK project.
Upvotes: 0