← 返回列表

Markdown与HTML富文本消息在解析时的转义与清洗

分类:Telegram频道发布于:2026-09-05

telegram中文搜索群组

在机器人、客服系统和内容管理后台中,Markdown 与 HTML 富文本消息经常需要被转换、转发或重新渲染。很多看似普通的文字,一旦包含反引号、下划线、尖括号或链接,就可能出现格式错乱、标签外露,甚至带来安全风险。

真正可靠的处理方式,不是简单地使用正则表达式替换字符,而是先明确消息格式,再执行转义、解析、清洗和输出。本文将结合 Telegram Bot API 的常见场景,说明两种富文本格式在解析时的差异、风险与实用处理流程。

🧩 一、为什么转义与清洗必须分开

转义的目标是让特殊字符失去语法含义,避免它们被误认为 Markdown 标记或 HTML 标签。清洗的目标则是删除不允许出现的标签、属性和链接协议,重点在于控制内容边界

例如,用户输入的下划线在 MarkdownV2 中可能触发斜体,尖括号在 HTML 中可能形成标签;如果应用同时支持两种格式,必须先记录当前的解析模式,不能使用同一套替换规则处理所有消息。

用户输入 → 识别格式 → 规范化文本 → 转义或解析 → 白名单清洗 → 发送或渲染

✍️ 二、Markdown 消息的转义规则

1. 普通 Markdown 与 MarkdownV2 不要混用

Telegram Bot API 常见的 MarkdownV2 对特殊字符要求更严格,通常需要处理下划线、星号、方括号、括号、反引号、波浪线、井号、加号、减号、等号、竖线、大括号、句号和感叹号等字符。

在没有格式需求的用户输入中,最安全的方式是逐字符转义,而不是把整段内容直接拼接进模板,否则用户输入可能改变原有消息结构。

function escapeMarkdownV2(text) {
  return text.replace(/[_*[\]()~`>#+\-=|{}.!]/g, '\\$&');
}

const safeText = escapeMarkdownV2(userInput);
bot.sendMessage(chatId, safeText, { parse_mode: 'MarkdownV2' });

2. 格式模板与用户内容要分层

推荐将机器人模板和用户输入分开处理,例如模板负责标题、加粗和按钮说明,用户输入只作为已经转义的变量插入。这样可以避免用户输入闭合一个未完成的粗体、链接或代码片段。

如果必须支持嵌套格式,应优先建立语法树或实体列表,不要连续调用多次 replace,因为前一次生成的反斜杠可能被后一次规则再次处理。

🌐 三、HTML 富文本消息的解析与实体编码

Telegram 的 HTML 解析模式并不是完整浏览器 HTML,而是只支持有限的格式标签,例如加粗、斜体、下划线、删除线、链接、行内代码和代码块等。具体能力还会受到 Bot API 版本与客户端表现的影响,因此不能把任意网页代码直接发送。

HTML 文本至少要正确处理三个核心字符:小于号应编码为 <,大于号应编码为 >,和号应编码为 &。属性中的双引号也应进行编码,避免破坏标签边界。

const message = '<b>通知</b>\n' + escapeHtml(userInput);

bot.sendMessage(chatId, message, {
  parse_mode: 'HTML'
});

需要特别注意双重转义:同一段文本不能先编码一次,又在发送前再次编码,否则用户看到的会是实体字符串,而不是正常字符。工程上应明确每个字段当前处于“原始文本”“已转义文本”还是“已解析实体”状态。

电报精准找群黑科技提示:

由于 Telegram 官方搜索对中文支持极差,很多优质的推广、技术和资源群组隐藏极深。如果你正在寻找相关的活跃社群,强烈推荐使用本站首页的 【TTSO - Telegram 智能搜索 Bot】。作为目前最好用的电报综合搜索导航,只需输入关键词,即可秒级触达数十万个精选 TG 中文群组、资源频道。一键直达,帮你节省 90% 的找群时间!

🛡️ 四、HTML 清洗不能只依赖正则表达式

正则表达式适合做简单检测,却不适合完整解析嵌套 HTML。面对不闭合标签、大小写混用、属性换行或编码绕过时,正则规则很容易漏判,甚至把安全标签误删。

更稳妥的方案是使用成熟的 HTML 解析器或清洗库,并建立标签白名单、属性白名单和协议白名单。通常应拒绝脚本、事件属性、内联样式、iframe、SVG,以及非必要的 data、javascript 等链接协议。

允许标签:b、strong、i、em、u、s、code、pre、a
允许属性:a[href]
允许协议:https、http
拒绝属性:onclick、onerror、style
拒绝标签:script、iframe、object、svg

如果内容最终只发送到 Telegram,也不要误以为平台会替应用完成全部安全工作;当消息同时显示在网页后台、日志系统或管理面板时,仍然必须在自己的渲染层执行清洗。

⚙️ 五、推荐的工程处理流程

第一步,识别来源和模式。明确消息来自用户、管理员还是系统模板,并确定使用 MarkdownV2、HTML 还是 Telegram MessageEntity。不要让前端传来的 parse_mode 直接决定后端行为。

第二步,统一换行和编码。将不同平台的换行符统一为换行,清理不可见控制字符,并限制异常长度。对于链接,还应检查协议、域名和是否包含危险跳转。

第三步,分别执行解析。Markdown 重点是保留合法语法并转义保留字符,HTML 重点是解析节点并按白名单清洗;两种流程完成后,再生成最终消息或实体。

第四步,建立失败回退。当 Telegram 返回实体范围错误、未闭合标签或消息长度超限时,应记录原始错误类型,并回退为纯文本发送,而不是反复重试同一份无效内容。

Telegram 的 MessageEntity 还涉及字符偏移量,部分接口按 UTF-16 代码单元计算长度。包含中文、表情符号或特殊字符时,应使用与平台一致的长度算法,避免加粗范围错位。

✅ 六、上线前的测试清单

测试时不要只验证正常句子,还应覆盖未闭合标记、连续反斜杠、多个表情、中文与英文混排、超长链接、换行代码块以及用户输入的尖括号。

同时检查显示结果、API 返回值和日志内容是否一致,并确认失败回退不会泄露令牌、内部路径或用户隐私。生产环境建议为每种解析模式保留独立测试用例。

□ 普通文本中的特殊字符可正常显示
□ MarkdownV2 标记不会被用户输入劫持
□ HTML 标签和属性均来自白名单
□ 链接协议经过校验
□ 超长或非法消息可回退为纯文本
□ 中文、表情符号的实体位置没有偏移

❓ 常见问题解答(FAQ)

MarkdownV2 是否比 HTML 更安全?

两者都可以安全使用,关键在于是否针对对应语法正确转义。MarkdownV2 主要防止格式字符被误解释,HTML 则需要额外执行标签、属性和链接协议清洗。

为什么 Telegram 消息会显示原始标签?

常见原因是没有设置正确的 parse_mode,或者标签不属于 Telegram 支持的子集。也可能是开发者提前把尖括号编码后,又把编码后的文本当作 HTML 模板发送。

能否用 replace 删除所有 HTML 标签?

不建议这样做,因为简单替换无法可靠处理嵌套结构和异常编码,也可能误删正文内容。应使用 HTML 解析器配合白名单清洗,并在输出层再次确认结果。

什么时候应该放弃富文本解析?

当消息来自不可信来源、格式损坏或接口持续返回解析错误时,建议回退为纯文本。稳定展示和信息完整性通常比勉强保留加粗、链接等样式更重要。

总结来看,转义解决语法冲突,清洗解决信任边界,实体化解决精确渲染。只要将三者拆分,并针对 Markdown 与 HTML 分别建立测试和回退机制,富文本消息就能在可读性、安全性与兼容性之间取得更好的平衡。

telegram搜
Telegram搜索入口客服ID@TTSO联系