所以我试图通读一个.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()
然后我的比较呢?
答案 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("</")
。