从文件中读取一行中的子字符串

时间:2015-03-02 22:46:26

标签: java string substring

所以我试图通读一个.txt文件并查找html标签的所有实例,将开始标签推送到堆栈,然后在找到结束标签时弹出它。现在我正在为以下行获取String out of bounds异常:

    if(scan.next().startsWith("</", 1))
            {
                toCompare = scan.next().substring(scan.next().indexOf('<'+2), scan.next().indexOf('>'));
                tempString = htmlTag.pop();
                if(!tempString.equals(toCompare))
                {
                    isBalanced = false;
                }
            }
            else if(scan.next().startsWith("<"))
            {
                tempString = scan.next().substring(scan.next().indexOf('<'+1), scan.next().indexOf('>'));
                htmlTag.push(tempString);
            }

它告诉我最后一个字母的索引是-1。我能想到的问题是所有scan.next()调用都移动到下一个字符串。如果是这种情况,我是否需要写

    toCompare = scan.next()

然后我的比较呢?

1 个答案:

答案 0 :(得分:0)

您的代码中存在两个主要问题:

  • 您正在调用scan.next()太多而且正如您所料,这会将扫描仪移动到下一个令牌。因此,最后一个将丢失并消失。
  • .indexOf('<'+2)未返回'<'的索引并将 2 添加到该位置,它将返回'>'的索引,因为您是将 2 添加到char <的int值(60; >有62)。你的问题索引 -1 “它告诉我最后一个字母的索引是-1。”)来自这个调用:.indexOf('<'+1)这个查找char '=',如果你的字符串不包含它,那么它将返回 -1 。如果您将 -1 作为起始位置,则对#substring(int, int)的调用将失败。

我建议使用以下两种方法来提取'<''>'之间的值:

public String extract(final String str) {
    if (str.startsWith("</")) {
        return extract(str, 2);
    } else if (str.startsWith("<")) {
        return extract(str, 1);
    }
    return str;
}

private String extract(final String str, final int offset) {
    return str.substring(str.indexOf('<') + offset, str.lastIndexOf('>'));
}

正如你所看到的,第一种方法为第二种方法评估正确的偏移以切断“偏移。记住我写的str.indexOf('<') + offset行为不同于你的{{ 1}}。

要解决您的第一个问题,请存储str.indexOf('<' + offset)的结果并将所有次出现替换为该临时字符串:

scan.next()

我想这可以帮助你解决问题。您还可以稍微改进一下代码,例如尽量避免两次调用final String token = scan.next(); if (token.startsWith("</")) { // removed the second argument final String currentTag = extract(token); // renamed variable final String lastTag = htmlTag.pop(); // introduced a new temporary variable if (!lastTag.equals(currentTag)) { isBalanced = false; } } else if (token.startsWith("<")) { htmlTag.push(extract(token)); // no need for a variable here } #startsWith("</")