Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

replaceAll for StringBuilder with regex support?

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?

like image 447
Jin Kim Avatar asked Jun 28 '13 14:06

Jin Kim


People also ask

Does replaceAll use regex?

The method replaceAll() replaces all occurrences of a String in another String matched by regex. This is similar to the replace() function, the only difference is, that in replaceAll() the String to be replaced is a regex while in replace() it is a String.

What does replaceAll \\ s+ do?

replaceAll() With a Non-Empty Replacement We've learned the meanings of regular expressions \s and \s+. Now, let's have a look at how the replaceAll() method behaves differently with these two regular expressions. The replaceAll() method finds single whitespace characters and replaces each match with an underscore.

What do the replaceAll () do?

The replaceAll() method returns a new string with all matches of a pattern replaced by a replacement . The pattern can be a string or a RegExp , and the replacement can be a string or a function to be called for each match.


3 Answers

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 Matchers work with more than just Strings: Matchers 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.

Working demo.

like image 102
Martin Ender Avatar answered Oct 18 '22 02:10

Martin Ender


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>"));
}

View a test code demo!

like image 44
Unihedron Avatar answered Oct 18 '22 00:10

Unihedron


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.

like image 3
David Ehrmann Avatar answered Oct 18 '22 00:10

David Ehrmann