Java中如何将HTML标签存入栈?标签计数为0问题求助
HTML标签栈计数始终为0的问题排查
尝试读取HTML.txt文件并将其中的HTML标签存入栈中,但开闭标签的计数始终为0,代码可编译运行但逻辑存在问题。
读取的文件第一行内容:
<html lang="en" style="">
当前使用的代码:
public boolean validateTags() throws FileNotFoundException { String oneLine = ""; String tag = ""; int space, closeTag; Scanner file = new Scanner(filename).useDelimiter("<"); //** ATTEMPT 1 ** space = oneLine.indexOf(' '); int openBracket = oneLine.indexOf('<'); oneLine = file.next(); while (file.hasNext()) { if (oneLine.startsWith("<") && oneLine.endsWith(">") && !oneLine.startsWith("<!")) { tag = oneLine.substring(openBracket, space); openTags.push(tag); } if (oneLine.startsWith("<") && oneLine.endsWith("/>")&& !oneLine.startsWith("<!")) { tag = oneLine.substring(openBracket,space); closeTags.push(tag); } if (!oneLine.startsWith("<") || !oneLine.endsWith(">")) { throw new InvalidHTMLException(); } } }
补充说明:曾尝试将Scanner改为Scanner file = new Scanner(new File(filename));,但触发了最终if语句中的InvalidHTMLException异常。
问题根源分析
- Scanner分隔符错误:使用
<作为分隔符后,file.next()获取的内容是<之后的部分(比如第一行的html lang="en" style="">),导致oneLine.startsWith("<")永远为false,所有标签判断的if条件都不会触发,计数自然为0。 - 变量初始化时机错误:
space和openBracket是在oneLine赋值前计算的,此时oneLine是空字符串,两个变量的值都是-1,即使进入if分支,substring也会抛出异常。 - 循环未更新
oneLine:循环内没有调用file.next()更新oneLine,始终处理第一次获取的内容,无法遍历文件所有内容。 - 整行标签判断过于严格:原代码要求每行必须是纯标签,否则抛出异常,但HTML文件中标签和文本混合存在,这会导致正常内容触发异常。
修正后的代码示例
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public boolean validateTags() throws FileNotFoundException { String oneLine; String tag; Scanner file = new Scanner(new File(filename)); while (file.hasNextLine()) { oneLine = file.nextLine().trim(); if (oneLine.isEmpty()) continue; // 跳过空行 // 匹配所有非注释的HTML标签 Pattern tagPattern = Pattern.compile("<(?!!)[^>]+>"); Matcher matcher = tagPattern.matcher(oneLine); while (matcher.find()) { String fullTag = matcher.group(); // 处理普通开标签(如<html>) if (fullTag.startsWith("<") && fullTag.endsWith(">") && !fullTag.startsWith("</") && !fullTag.endsWith("/>")) { int endIndex = fullTag.indexOf(' '); endIndex = endIndex == -1 ? fullTag.indexOf('>') : endIndex; tag = fullTag.substring(1, endIndex); openTags.push(tag); } // 处理闭合标签(如</html>) else if (fullTag.startsWith("</") && fullTag.endsWith(">")) { tag = fullTag.substring(2, fullTag.indexOf('>')); closeTags.push(tag); } // 处理自闭标签(如<img/>) else if (fullTag.endsWith("/>")) { int endIndex = fullTag.indexOf(' '); endIndex = endIndex == -1 ? fullTag.indexOf('/') : endIndex; tag = fullTag.substring(1, endIndex); // 自闭标签可根据需求同时存入开闭栈或单独处理 openTags.push(tag); closeTags.push(tag); } } } file.close(); // 可添加标签匹配验证逻辑(如栈的弹出匹配) return true; }
修正要点说明
- 移除错误的分隔符设置,改为逐行读取文件,保留标签的
<前缀。 - 使用正则表达式精准提取每行中的所有非注释HTML标签,避免整行判断的局限性。
- 分别处理开标签、闭合标签、自闭标签,正确截取标签名。
- 循环内更新
oneLine并跳过空行,确保遍历文件所有内容。 - 移除了过于严格的整行标签判断,适配HTML文本与标签混合的结构。
内容的提问来源于stack exchange,提问作者ILoveMusic
相关产品推荐
相关产品推荐

