正则表达式可快速剥离html标签,但仅适用于简单场景;应匹配宽松的尖括号对,注意注释、cdata和自闭合标签;msvc旧版std::regex存在bug;手动状态机更可靠,用in_tag标志控制字符保留。

用正则表达式快速剥离HTML标签(C++11及以上)
标准库 std::regex 能应付大多数简单HTML清洗场景,但要注意它不解析嵌套或 malformed 标签,只做字符串层面的模式替换。
常见错误是写成 R"(]*>)" 却忽略换行、注释(<!-- ... -->)、CDATA段或自闭合标签(如
<br>),导致残留。实际应匹配更宽松的“尖括号对”:
- 使用
std::regex_replace(str, std::regex(R"(]*>)"), "")可清除大部分标签 - 若需处理注释,额外加一条:
std::regex_replace(str, std::regex(R"(<!--.*?-->)"), "")(需开启std::regex_constants::dot_not_newline或逐行处理) - 注意:MSVC 的
std::regex在旧版本(如 VS2015)中 bug 较多,建议升级或改用 Boost.Regex / PCRE2
手动扫描比正则更可靠(无依赖、可控性强)
当输入不可信(比如含畸形标签、JS混淆、实体编码)时,正则容易漏删或误删。手动状态机虽代码稍长,但逻辑清晰、边界明确。
核心思路是遍历字符,用布尔标志 in_tag 记录是否在 和 <code>> 之间:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 遇到
' → 设 <code>in_tag = true,跳过该字符 - 在
in_tag状态下,跳过所有字符直到遇到'>',然后设in_tag = false - 不在
in_tag状态时,把当前字符追加到结果中 - 注意处理
' 出现在属性值里的情况(如 <code>value="a<b>c"</b>)——严格来说这不属于标签,但手动扫描默认不识别引号上下文,所以会误删;如需精确,必须实现引号配对逻辑
用第三方库(如 Gumbo Parser)做真正解析式清理
如果原始字符串是完整 HTML 片段,且需要保留文本结构(比如换行、空格语义)、过滤特定标签(只删 <script></script> 不删 <p></p>),正则和手动扫描都不够用。
Gumbo 是 Google 开发的符合 HTML5 规范的 C 解析器,C++ 可直接调用:
- 调用
gumbo_parse()得到 DOM 树,递归遍历节点,对node->type == GUMBO_NODE_TEXT的内容提取并拼接 - 相比正则,它能正确处理
实体、<code>、命名空间前缀等边缘情况 - 编译需链接
-lgumbo,Windows 下推荐用 vcpkg 安装:vcpkg install gumbo - 性能开销比正则大一个数量级,但换来的是确定性 —— 你删掉的,一定是标签,不是文本里的合法字符
别忽略编码和实体问题
纯删标签不等于得到可读文本。HTML 中常见 &、、<code> 等实体,它们不是标签,但显示为特殊字符。
-
std::regex_replace或手动扫描后,建议再做一次实体解码(可用简易映射表,或引入htmlcxx库的HTMLParser::decodeEntities()) - 若源字符串是 UTF-8 编码,确保你的程序以 UTF-8 读取并输出,否则中文等字符会乱码 —— 这和删标签无关,但常一起暴露
- 某些 CMS 输出的 HTML 含 BOM 或混合编码(如 GBK 内嵌 UTF-8),此时先检测/转换编码比硬删标签更重要
真正难的不是“怎么删”,而是“删完之后用户看到的是否符合预期”。标签只是表层,编码、实体、DOM 结构语义才是影响结果的关键变量。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










