Replacing all occurrences of a substring in a string without using regex

Posted on

Problem

Problem Statement:

Given two strings, base and remove, return a version of the base
string where all instances of the remove string have been removed (not
case sensitive). You may assume that the remove string is length 1 or
more. Remove only non-overlapping instances, so with “xxx” removing
“xx” leaves “x”.


withoutString(“Hello there”, “llo”) → “He there”

withoutString(“Hello there”, “e”) → “Hllo thr”

withoutString(“Hello there”, “x”) → “Hello there”

Please feel free to review the code below:

public String withoutString(String base, String remove) {
   final int rLen = remove.length();
   final int bLen = base.length();
   String op      = "";

   for(int i = 0; i < bLen;)
   {
        if( !(i + rLen > bLen) && base.substring(i, i + rLen).equalsIgnoreCase(remove) )
        {
            i += rLen;
            continue;
        }
        op += base.substring(i, i + 1);
        i++;
   }

   return op;   

}

Solution

Using a StringBuilder should always be your preferred choice when doing String manipulation. It does not always make sense, but almost always.

Additionally, indexOf takes a ‘from’ location, and it makes the whole thing easier…. Convert both inputs to lower-case, then do the matching using the lower-case versions, but the substrings using the unknown-case.

The complicated assign-in-where-condition logic makes the loop conditions easier, but you do need to understand what this does:

while ((find = lcbase.indexOf(lcremove, previous)) >= 0) {

it searches for thelower-case remove from the previous position, saves the value to find, and checks that the result is ‘positive’…. all in the condition of a while loop.

The full code is:

public static String withoutString(String base, String remove) {

    final String lcbase = base.toLowerCase();
    final String lcremove = remove.toLowerCase();
    int find = 0;
    int previous = 0;
    StringBuilder result = new StringBuilder(base.length());
    while ((find = lcbase.indexOf(lcremove, previous)) >= 0) {
        result.append(base.substring(previous, find));
        previous = find + remove.length();
    }
    result.append(base.substring(previous));
    return result.toString();

}

See this running inideone

Leave a Reply

Your email address will not be published. Required fields are marked *