New Rule to check if first argument of String::replaceAll is really a regexp?

Hi,

Sometimes method String::replaceAll is used but the first argument is not a regexp.
In this case replaceAll is not the right method, String::replace should be used which doesn’t use underlying regexp/Pattern/compil stuff.
I think that replaceAll is used because it’s what user means : replace all occurence of this string x with string y.
I suggest a rule that check if the first argument of String::replaceAll contains a regular expression constructs like | . \d?*+ . If not raise an performance warning : “Use of a regexp method but your first argument is not using regexp contructs”.

Any thoughts on this ?

Hey @farnulfo,

Looks like a good idea of a rule to me. However, detecting what could be a wrong usage of a regex with String::replaceAll is already covered by S4248 (Regex patterns should not be created needlessly), although your use case is slightly different.

What do you think of the following rule description?

Use String::replace instead of String.replaceAll

When using String::replaceAll, be sure to provide a regular expression as first argument. If it’s not the case, then simply use String::replace, which does exactly the same thing, without the performance issues of a regex.

The underlying implementation of String::replaceAll calls the java.util.regex.Pattern.compile() method each time it is called, which have a significant performance cost, and therefore should be used sensibly. See related rule S4248 (Regex patterns should not be created needlessly).

This rule raises an issue every time String::replaceAll is called with a String as first parameter which doesn’t contains special regex character or pattern.

Noncompliant Code Example

String init = "Bob is a Bird... Bob is a Plane... Bob is Superman!";
String changed = init.replaceAll("Bob is", "It's"); // Noncompliant

Compliant Solution

String init = "Bob is a Bird... Bob is a Plane... Bob is Superman!";
String changed = init.replace("Bob is", "It's");

Or, with a regex:

String init = "Bob is a Bird... Bob is a Plane... Bob is Superman!";
String changed = init.replaceAll("\\w*\\sis", "It's");

Hi @Michael,

Rule description looks good ! Thanks.
May I suggest to add some context to help to understand why rule is raised like “your string doesn’t contains special regex character or pattern” ?

1 Like

I added the following paragraph to the description.

WDYT?

1 Like

Great !

Thanks you

Okay, here are the related JIRA ticket:

Cheers,
Michael

1 Like