Search code examples
javastringindexingreplaceall

What is causing this StringIndexOutofBounds exception?


I have this code to find a palindrome below; I need to be able to remove all numbers, spaces, and punctuation from the user input String, so I've been using replaceAll. When I only had String input = str.toLowerCase(); and String newInput = input.replaceAll("[0-9]+", ""); in my code, there was no problem. It removes the numbers and continues. However when I try to add punctuation or a space, I get a StringIndexOutOfBoundsException.

Example: I input Anna.55

The line underneath all of the replaceAll statements, System.out.println(newestInput);, will print out anna but immediately throws the error when reaching the while loop and states that the problem is with the index of 6.

From my understanding (I am still learning Java and am unfamiliar with replaceAll) removing the spaces with replaceAll("\\s", "") would remove the spaces left by the previous replaceAll statements and thus there would be no index 6 (or even 4). How is there an error at index of 6 when it no longer exists?

import java.util.Scanner;

public class PalindromeTester {
    public static void main (String[] args) {
        String str;
        String another = "y";
        int left;
        int right;
        Scanner scan = new Scanner (System.in);
        while (another.equalsIgnoreCase("y")) {
            System.out.println("Enter a potential palindrome:");
            str = scan.nextLine();  
            left = 0;
            right = str.length() - 1;           
            String input = str.toLowerCase(); 
            String newInput = input.replaceAll("[0-9]+", "");
            String newerInput = input.replaceAll("\\W", "");
            String newestInput = newerInput.replaceAll("\\s", "");           
            System.out.println(newestInput);
            while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) {
                left++;
                right--;
            }
             System.out.println();
            if (left < right)
                System.out.println("That string is not a palindrome.");
            else 
                System.out.println("That string is a palindrome.");
            System.out.println();
            System.out.print ("Test another palindrome (y/n)? ");
            another = scan.nextLine();
        }
    }
}

Solution

  • You're using right = str.length() - 1; to determine the length of the input, but you modify what was input after it (and what you compare)...

    String input = str.toLowerCase();
    String newInput = input.replaceAll("[0-9]+", "");
    String newerInput = input.replaceAll("\\W", "");
    String newestInput = newerInput.replaceAll("\\s", "");
    
    System.out.println(newestInput);
    while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) {
    

    Which means the String is no longer the original length, in your example, it's 1 character shorter

    Instead, calculate the length of the newestInput instead

    right = newestInput.length() - 1;
    System.out.println(newestInput);
    while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) {