c++ - 用纯C++解析简单的html

标签 c++ api parsing vector

在我的应用程序中,我需要解析简单的 HTML 代码,而不使用尽可能少的外部库。我的 HTML 看起来像

<p> First Content is P </p><h2>Header</h2><p> Text under header </p>
<h2>Header 2</h2><p> Paragraph </p>
<h3>yep</h3><p> no </p>

我的 html 仅包含标签 p、h2、h3。我得到了以下结构:

struct Elements {
    std::string tag;
    std::string content;
};

std::vector<Elements> elems;

所以我的目标是解析 vector 中的每个元素后应包含如下数据:

tag = "h2"
content = "Header"

tag = "p"
content = "First Content is P"

PP:我需要按照 HTML 中显示的顺序获取元素。

编辑:

我刚刚用 javascript 做了这个,它工作正常,但我基本上不知道如何用 c++ 写下来:

var a = "<p> First Content is P </p><h2>Header</h2><p> Text under header </p>" +
    "<h2>Header 2</h2><p> Paragraph </p>" +
    "<h3>yep</h3><p> no </p>";

var output = [];

a.replace(/<\b[^>]*>(.*?)<\/(.*?)>/gmi, function(m, key, value) {
    output.push({
        tag: value,
        data: key
    });
})

/*
    output:
        { tag: "p", data: "First Content is P"},
        { tag: "h2", data: "Header" }
        .....
 */

最佳答案

只有这三个元素,并且没有缺少关闭标签。而且标签上似乎没有任何属性,甚至元素内也没有任何元素。标签内也没有空格。

那么您没有解析 HTML。您正在解析一种特殊的语言,它是 HTML 的子集(好吧,甚至不是真正的子集,因为您的文档无法验证)。

您可能有充分的理由不想使用 HTML 解析器来解析这种特殊语言。例如,完整的 HTML 解析器的代码相当大,否则可能不需要位于您正在为其编写的非常小的嵌入式设备上。更有可能的是,这是一项学习作业,目标是让您操作字符串而不是来选择最佳工具来生成所需的输出。我假设您必须避免使用 HTML 库,而不进一步考虑原因。

那么,如何解析这种特殊的语言呢?如何解析任何东西。鉴于我上面列出的所有限制,您可以非常简单地做到这一点:

  • 查找三个子字符串中任意一个的字符串中的第一个实例 <p> , <h2> , <h3> 。这是您的开始标签。
  • 查找相应关闭标记的第一个实例。
  • 之间的所有内容都是元素的内容。在您的示例中,您还修剪了内容两端的空白。构建 Elements对象并将其添加到您的 vector 中(顺便说一句,请考虑使用单数类名,而不是复数)。
  • 重复字符串的其余部分。

就是这样。您可以使用正则表达式来做到这一点,但我的总体感觉是,既然您您想在 C++ 中执行此操作,那么您也可以在 C++ 中执行此操作。不需要引入另一种语言,无论正则表达式有什么优点和局限性,它们肯定是另一种语言。

但是,我上面列出的额外限制可能无法得到保证。如果您以后想要支持标签内的空格怎么办?还有属性? XML 命名空间呢?还有评论?那么您会希望刚刚使用了 HTML 解析器。因此,您对固定的简单 HTML 子集所做的操作不同于对重要子集或将来可能变得重要的子集所做的操作。

关于c++ - 用纯C++解析简单的html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23072690/

相关文章:

c++ - 指向空指针

c++ - 使用 MinGW 静态链接到 Windows 上的 libarchive

api - 用于检索对象集基数的 REST API

java - 上传文件到Liferay服务器

java - 有 OpenGrok API 吗?

parsing - 编写 Z80 汇编程序 - 词法 ASM 并使用组合构建解析树?

C++ boost 日志记录 : how to zip logs?

c++ - 如何为成员的成员创建 boost multi_index 键?

regex - 我可以使用什么正则表达式来查找逗号分隔列表中的 Nᵗʰ 条目?

php - 如何将字符串转换为包含数学运算的数字?