使用 Java 解析 HTML 标签
Posted
技术标签:
【中文标题】使用 Java 解析 HTML 标签【英文标题】:Parsing HTML tags using Java 【发布时间】:2014-06-06 02:50:05 【问题描述】:我正在尝试创建一个 html 解析器来检查 HTML 标记并验证是否存在与每个打开标记相对应的结束标记。
我现在部分工作,我相信逻辑是正确的,但我在正确获取令牌时遇到问题。当我运行我拥有的代码时,它需要很多空标记,与其他非空标记相比,显然会产生错误。
我想知道如何让它从我的 HTML 文件中读取,但只将内容放入 之间的标记中。我也不希望将任何额外数据(例如 h1 标签之间的文本)考虑在内。
这是一个学校作业,我相信教授希望我们在不使用第三方程序(如 JTidy)的情况下这样做。
非常感谢任何帮助。
import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.*;
public class HTMLDriver
public static void main(String [] args) throws IOException
// declare variables
QueueReferenceBased queue = new QueueReferenceBased();
// Create a scanner object
Scanner in = new Scanner(System.in);
System.out.println("What is your html file name?");
String fileName = in.next();
File userFile = new File(fileName);
if (!userFile.exists())
System.out.println("File does not exist. This program will now exit.");
System.exit(0);
Scanner inputFile = new Scanner(userFile);
while (inputFile.hasNext())
String str = inputFile.nextLine();
StringTokenizer st = new StringTokenizer(str,"<>");
//Adds tokens to queue
while(st.hasMoreTokens())
String token = st.nextToken();
Tag t = new Tag(token);
queue.enqueue(t);
//Creates Stack
StackReferenceBased stack = new StackReferenceBased();
//Loops through queue if not empty
while(!queue.isEmpty())
Object obj = queue.dequeue();
Tag t2 = (Tag)obj;
if(t2.getOpen() == true)
stack.push(t2);
if(t2.getOpen() == false)
if(stack.isEmpty())
System.out.println("There is no match for the " + t2 + " tag");
else
Object obj2 = stack.pop();
Tag t3 = (Tag)obj2;
//Make tag class and check equality
if(t2.getTag().equals(t3.getTag()))
System.out.println(t2 + " matches " + t3);
else
System.out.println("Found " + t2 + " to match " + t3 + " terminating program");
System.exit(0);
【问题讨论】:
【参考方案1】:不要这样做。 Html 在这方面是臭名昭著的。一些标签没有打开/关闭 -- 然后就是所有格式错误的 HTML 和浏览器的怪癖。
除非您的教授明确禁止您使用 3rd 方库,否则尝试在强大的规模上是疯狂的。在 XML 上,这是可以管理的。
如果你真的,真的必须自己做,使用正则表达式可以获得不错的结果
Pattern p = Pattern.compile("<(.*)>") // will get your started. you can then do:
Matcher m = p.matcher();
m.group( ... ) // this will get you everything between parentheses in the regex
【讨论】:
我不能再反对了。浏览器使用相同方式的更复杂的过程来解析 HTML,按顺序标记输入流并构建标签标记堆栈。 OP 正在学习这方面的基础知识。在解析 HTML 时,正则表达式是一条死胡同。 我以前从未使用过正则表达式,所以我对如何正确使用有点困惑。我尝试搜索一下教程,但我仍然感到困惑。当我使用您发布的代码时,它给了我一个错误,指出 Matcher m = p.matcher(); 存在错误并且它不能应用于给定的类型。我应该把我的字符串作为参数放在那里吗?我也对 m.group 的工作方式感到困惑。那是我把绳子放进去的地方吗?对不起,如果我看起来很无能,这是我第一次使用正则表达式,它们对我来说有点难。 自己做这件事是死路一条。我说清楚了。如前所述,您可以使用正则表达式获得“可管理”的结果。至于浏览器,任何 Web 开发人员都可以告诉您,每个浏览器都充满了怪癖和错误。它们既可以是复杂的,也可以是错误的。 Litheon,我很高兴提供一些正则表达式指针——给我发消息。我对你最强烈的建议是验证这是你的导师想要的以上是关于使用 Java 解析 HTML 标签的主要内容,如果未能解决你的问题,请参考以下文章
使用php simple html dom parser解析html标签