Abhinandan
Abhinandan

Reputation: 87

Why does the following exception showing -4 index specifically instead of -1?

I am trying to get a substring out of a string. I have written logic to provide a start index and an end index but getting below exception. The code is:

final int startIndex = header.indexOf(startValue + ":")
                + (startValue + ":").length();
final int endIndex = header.indexOf(endValue + ":");
return header.substring(startIndex, endIndex).trim();

The exception:

'String index out of range: -4' java.lang.StringIndexOutOfBoundsException: String index out of range: -4 at java.lang.String.substring(String.java:1967)

Any help would be appreciated.

Upvotes: 3

Views: 110

Answers (2)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521239

This is not an exact answer or correction, because I think your approach needs to change. I suggest using a regex based approach to find all key value pairs in the body of your text. Consider this version:

String input = "<html> <head></head> <body> Sent: Thu Feb 04 19:06:38 IST 2021 From: [email protected] To: [email protected],[email protected] Subject:";
String pattern = "\\b(\\S+): (.*?)(?= \\S+:)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(input);

while (m.find()) {
    System.out.println("Found: (" + m.group(1) + ", " + m.group(2) + ")");
}

This prints:

Found: (Sent, Thu Feb 04)
Found: (From, [email protected])
Found: (To, [email protected],[email protected])

You may iterate over the text and search for whatever key/value you need. Avoid substring operations in this case because it leaves too many edge cases open.

Upvotes: 0

Eran
Eran

Reputation: 393821

The relevant code of substring is:

1965    int subLen = endIndex - beginIndex;
1966    if (subLen < 0) {
1967        throw new StringIndexOutOfBoundsException(subLen);
1968    }

If you see -4 in the exception's message, this means endIndex - beginIndex == -4.

Obviously, endIndex should be larger than or equal to beginIndex, so that the difference won't be negative.

Looking at the full method (this version of the code seems to match your version, based on the line number - 1967 - in which the exception was thrown):

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > value.length) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    int subLen = endIndex - beginIndex;
    if (subLen < 0) {
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
            : new String(value, beginIndex, subLen);
}

you can see that you would have gotten -1 in the error message if beginIndex was -1.

But if beginIndex is non-negative, and endIndex is not too large, the number you get in the exception's message is endIndex - beginIndex.

Upvotes: 5

Related Questions