是什么导致了这个 StringIndexOutofBounds 异常?

What is causing this StringIndexOutofBounds exception?

我有这段代码可以在下面找到一个回文;我需要能够从用户输入的字符串中删除所有数字、space 和标点符号,所以我一直在使用 replaceAll。当我的代码中只有 String input = str.toLowerCase();String newInput = input.replaceAll("[0-9]+", ""); 时,没有问题。它删除数字并继续。但是,当我尝试添加标点符号或 space 时,我得到了 StringIndexOutOfBoundsException。

例子:我输入Anna.55

所有 replaceAll 语句下方的行 System.out.println(newestInput); 将打印出 anna 但在到达 while 循环时立即抛出错误并指出问题出在指数 6.

根据我的理解(我仍在学习 Java 并且不熟悉 replaceAll)用 replaceAll("\s", "") 删除 space 会删除 space s 由前面的 replaceAll 语句留下,因此不会有索引 6(甚至 4)。索引 6 不再存在时,如何出现错误?

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();
        }
    }
}

您正在使用 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) {

这意味着 String 不再是原始长度,在您的示例中,它缩短了 1 个字符

而是计算 newestInput 的长度

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

首先要做两件事:

我觉得

input.replaceAll("\W", "");

应该是

newInput.replaceAll("\W", "");

权利应该在令牌被移除之后而不是之前计算,像这样:

left = 0;
String input = str.toLowerCase(); 
String newInput = input.replaceAll("[0-9]+", "");
String newerInput = newInput.replaceAll("\W", "");
String newestInput = newerInput.replaceAll("\s", "");
right = newestInput.length() - 1;

否则 right 可以大于 newestInput 的长度,你会得到一个 java.lang.StringIndexOutOfBoundsException.

实际上,一种更简单的方法来测试一个字符串是否是回文,就是前后是否相同。