I have String str
, from which I want to extract the sub-string excluding a possible prefix "abc"
.
The first solution that comes to mind is:
if (str.startsWith("abc"))
return str.substring("abc".length());
return str;
My questions are:
Is there a "cleaner" way to do it using split
and a regular expression for an "abc"
prefix?
If yes, is it less efficient than the method above (because it searches "throughout" the string)?
If yes, is there any better way of doing it (where "better way" = clean and efficient solution)?
Please note that the "abc"
prefix may appear elsewhere in the string, and should not be removed.
Thanks
Removing of a prefix from Groovy strings consists of two steps: first confirmation and then removal. Both of these steps can be performed using the StringGroovyMethods class that offers many utility methods for string manipulations.
Groovy has added the minus() method to the String class. And because the minus() method is used by the - operator we can remove parts of a String with this operator. The argument can be a String or a regular expression Pattern. The first occurrence of the String or Pattern is then removed from the original String.
Shorter than above code will be this line:
return str.replaceFirst("^abc", "");
But in terms of performance I guess there wont be any substantial difference between 2 codes. One uses regex and one doesn't use regex but does search and substring.
Using String.replaceFirst
with ^abc
(to match leading abc
)
"abcdef".replaceFirst("^abc", "") // => "def"
"123456".replaceFirst("^abc", "") // => "123456"
"123abc456".replaceFirst("^abc", "") // => "123abc456"
A regex-free solution (I needed this because the string I'm removing is configurable and contains backslashes, which need escaping for literal use in a regex):
Apache Commons Lang StringUtils.removeStart(str, remove)
will remove remove
from the start of str
using String.startsWith
and String.substring
.
The source code of the method is informative:
public static String removeStart(final String str, final String remove) {
if (isEmpty(str) || isEmpty(remove)) {
return str;
}
if (str.startsWith(remove)){
return str.substring(remove.length());
}
return str;
}
Try this
str = str.replaceAll("^abc", "");
String#split
can do this, but it's not better solution. Actually it'll be vague and I wouldn't recommend using it for that purpose.startsWith
.String#startsWith
was designed for that.You can easily measure the time that takes a code to run. Here what you can do:
Create a big loop, inside it you can append the counter of it to some dummy String in order to simulate the Strings you want to check, then try to have startsWith
once, and replaceAll
after:
for(int i = 0;i<900000;i++) {
StringBuilder sb = new StringBuilder("abc");
sb.append(i);
if(sb.toString().startsWith("abc")) { ... }
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~130
for(int i = 0;i<900000;i++){
StringBuilder sb = new StringBuilder("abc");
sb.append(i);
sb.toString().replaceAll("^abc", "");
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~730
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With