从文件
问题描述:
中读取一行中创建一个子串所以我想通读一个.txt文件并查找所有html标签的实例,将打开的标签推入堆栈,然后在找到结束标签时将其弹出。现在我得到下面一行的字符串越界异常:从文件
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()
然后等我的比较?
答
你在你的代码有两个主要问题:
- 你打电话
scan.next()
方式太多,如您所愿,这将扫描仪移动到下一个标记。因此,最后一个将会消失。 -
.indexOf('<'+2)
不返回'<'
的指标,并增加了到该位置,则返回的'>'
的指标,因为你要添加到焦炭<
(60的int值;>
有62个)。你的问题与指数-1(“它告诉我,最后一个字母的索引是-1。”)来自此调用:.indexOf('<'+1)
此查找字符'='
,如果您的字符串不包含那个,那么它将返回-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('>'));
}
正如你可以看到,第一种方法计算正确偏移用于要么切断第二种方法“offset。请注意,我写了str.indexOf('<') + offset
其行为与您的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("</")
和#startsWith("<")
两次。
+0
感谢大家的帮助。我昨天晚上修好了它。我只是做了tempString = scan.next(),并做了所有评估。 – 2015-03-03 23:29:55
删除**'else' **运算符。 – 2015-03-02 22:48:44
如果你已经修复@Pshemo告诉你的话,那么不要奇怪'str.substring(str.indexOf(''))'将永远是一个空字符串。并且'str.indexOf(' Tom 2015-03-02 22:54:54
当然,所有'scan.next()'调用都在继续到下一个字符串。这就是为什么该方法被命名为* next *,以获得* next *标记。 – 2015-03-02 22:55:29