How can I efficiently manipulate digits in a string without using RegEx in Java? I am reading a book with different quizzes about coding interviews.
Please implement a function that increments a string based on the rules below:

It should take the string of unknown length and increment the numberic ending of that string by 1.
If numberic ending is overflown it must be reset.
Don't use regular expressions

Examples of correct functionality are the following:
assertEquals(&quot;000003&quot;, increment(&quot;000002&quot;));
assertEquals(&quot;000000&quot;, increment(&quot;999999&quot;));
assertEquals(&quot;GL-322&quot;, increment(&quot;GL-321&quot;));
assertEquals(&quot;GL-000&quot;, increment(&quot;GL-999&quot;));
assertEquals(&quot;DRI000EDERS1RE&quot;, increment(&quot;DRI000EDERS0RE&quot;));
assertEquals(&quot;DRI000EDERS0RE00000&quot;, increment(&quot;DRI000EDERS0RE99999&quot;));

Here is my solution, I am sure it could be vastly more efficient / succinct:
public class Increment {

    static String padLeftZeros(String inputString, int length) {
        if (inputString.length() &gt;= length) {
            return inputString;
        }
        StringBuilder sb = new StringBuilder();
        while (sb.length() &lt; length - inputString.length()) {
            sb.append('0');
        }
        sb.append(inputString);

        return sb.toString();
    }

    static String increment(String referenceNumber) {

        // Finding the last digit index in referenceNumber
        int indexLastDigit = -1;
        for (int i = 0; i &lt; referenceNumber.length(); i++){
            try {
                Integer.parseInt(String.valueOf(referenceNumber.charAt(i)));
                indexLastDigit = i;
            } catch (NumberFormatException nfe) {
            }
        }

        // Finding the first digit index of the last digit group in referenceNumber
        int indexFirstDigit = -1;
        for (int i = indexLastDigit; i &gt;= 0; i--){
            try {
                Integer.parseInt(String.valueOf(referenceNumber.charAt(i)));
                indexFirstDigit = i;
            } catch (NumberFormatException nfe) {
                break;
            }
        }

        // Checking if numberToIncrement needs reset or not
        String numberToIncrement = referenceNumber.substring(indexFirstDigit, indexLastDigit + 1);
        boolean isReset = true;
        for (int i = 0; i &lt; numberToIncrement.length(); i++){
            if (numberToIncrement.charAt(i) != '9') {
                isReset = false;
            }
        }

        // Incrementing or resetting number
        StringBuilder incrementedNumberSB = new StringBuilder();
        int incrementedNumberInt;
        if (isReset) {
            for (int i = 0; i &lt; numberToIncrement.length(); i++){
                incrementedNumberSB.append(&quot;0&quot;);
            }
        } else {
            incrementedNumberInt = Integer.parseInt(numberToIncrement) + 1;
            incrementedNumberSB.append(incrementedNumberInt);
        }

        // Creating result string according to referenceNumber structure
        String incrementedNumberString = padLeftZeros(incrementedNumberSB.toString(), numberToIncrement.length());
        String prefix = referenceNumber.substring(0, indexFirstDigit);
        String suffix = referenceNumber.substring(indexLastDigit + 1, referenceNumber.length());
        String result = &quot;&quot;;

        if (prefix.length() &gt; 0) {
            result += prefix;
        }
        result += incrementedNumberString;
        if (suffix.length() &gt; 0) {
            result += suffix;
        }

        return result;

    }

}
TL;DR
private String increment(String input){
    char[] chars = input.toCharArray();

    boolean stopLoop = false;
    for(int i = chars.length - 1; i &gt;= 0; i--){
        char character = chars[i];
        switch (character) {
            case '0', '1', '2', '3', '4', '5', '6', '7', '8' -&gt; {
                chars[i] = (char) (character + 1);
                stopLoop = true;
            }
            case '9' -&gt; chars[i] = '0';
            default -&gt; {
                if(i + 1 &lt; chars.length &amp;&amp; chars[i + 1] == '0')
                    stopLoop = true;
            }
        }

        if(stopLoop)
            break;
    }

    return  new String(chars);
}

The quizzes of the coding interviews have some goals:

To check if the knowledge that the candidate claims is true.
To filter candidates when you have too many applications.
To know if you think beyond the obvious solution.
To know how deep you know about a language, or a version of it.
To check if you have some knowledge of data structures, algorithms
and time / space complexity of algorigthms.

Here the obvious solution is to work with Strings. Knowing that String in Java are immutable, you have to do all the stuff splitting and concatenating Strings. My proposal is to convert the String into a char array, work with it, and convert it back to an array.
The cost in time of reading and writting into an array is constant, while making all the work with strings has a higher time cost. In an interview is not so important, but for a backend position it is.
Is the char array the best thing ever? It is not, specially in this example. The good of it, is that you can use it like an integer of one byte space in memory. The bad, is because that behaviour, the editor wont tell you that you are writting 0 instead of '0'. 0 is the value of the NUL Ascii character. The Ascii value of '0' is 48. Well, this problem is designed to know if you write too error prone code.
When you have the char array, you traverse it backwards. To traverse backwards is more error prone than to traverse forwards (IndexOutOfBoundExceptions). So, it is another way to check how many errors do you write without the help of your editor, or without compiling several times.
Because you can use char as a value, it is perfect to use it into a switch statement. The first nine cases (from '0' to '8' character) share the same behaviour and code: Increment to next character and end the edition of the characters.
The case of character '9' requires to replace this character with '0' and check the previous character in the array.
The default case is the trickiest. It ignores the characters that aren't numbers if they appear before the characters that are numbers (remember, it is backwards traversing). When one number appears there are two options: the first option is one of the first nine cases, the other option is the case of a '9' converted into a '0'. So, if you find a non number character followed of a '0' the algorithm finishes.
The last step is to convert the char array back into a String, what you can do easily calling one of the String constructors.
You won't face this kind of problem in real life. You will use regular expresions. It is just to check you knowledge, in this case about Java. If you find a problem which solution is too complicate, try a less obvious one.
I hope it helped you.