← 返回列表

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

分类:Telegram群组发布于:2026-09-06

telegram中文搜索群组

🧭 痛点导言:为什么群消息一转发就“变样”

在 Telegram 群组、客服系统或内容管理后台中,Markdown 与 HTML 富文本经常同时出现。用户输入的星号、下划线、尖括号和链接,如果没有经过正确的转义与清洗,就可能造成格式错乱、消息发送失败,甚至给后台网页带来脚本注入风险。

这类问题的核心并不是“把特殊字符替换掉”这么简单,而是要区分语法解析、字符转义、标签白名单和安全过滤四个环节。尤其是 Telegram Bot API 只支持受限的 MarkdownV2 和 HTML,并不等同于浏览器完整支持的 Markdown 或 HTML。

🔍 一、先判断消息到底由谁解析

同一段文本在浏览器、Markdown 编辑器、Telegram 客户端和自建机器人后台中,可能得到完全不同的结果。因此,处理群消息前必须先确认目标平台、解析模式以及消息是否会被二次渲染。

Telegram 机器人常见的格式模式包括 MarkdownV2、HTML,以及直接提交实体信息的方式。MarkdownV2 更适合程序生成的轻量格式,HTML 更适合明确控制标签的通知消息,而实体模式可以减少整段文本被重复解析的风险。

{
  "chat_id": -1001234567890,
  "text": "<b>系统通知</b>:任务已完成",
  "parse_mode": "HTML"
}

需要特别注意,MarkdownV2 与 HTML 不能混用。例如在 HTML 模式中写入 Markdown 的星号,通常只会被当作普通字符;而把 HTML 标签直接放入 MarkdownV2,也不会自动获得浏览器式的解析效果。

🛡️ 二、转义不是清洗:两者解决的问题不同

1. 转义:保护文本不被误认为语法

转义的作用是告诉解析器:“这只是用户输入的普通文字,不是命令或标签。”例如,用户输入的“小于号”在 HTML 模式中应该转换为实体,否则解析器可能将后续内容当成标签的一部分。

HTML 消息通常需要重点处理 &、<、> 和引号。如果文本会被放进链接属性中,还必须确保属性值经过正确编码,并使用成对的英文引号包裹。

function escapeTelegramHtml(value) {
  return value
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

上面的代码用于把用户输入安全地放进 HTML 文本中,但它不会自动生成粗体、链接或换行格式。如果业务确实需要保留用户的富文本,就应当先解析,再根据白名单重新生成安全格式,而不是直接信任原始标签。

2. MarkdownV2 的特殊字符

MarkdownV2 对特殊字符较为敏感,常见需要转义的字符包括下划线、星号、方括号、圆括号、波浪号、反引号、尖括号、井号、加号、减号、等号、竖线、大括号、句号和感叹号。

实际开发时不能只做一次全局替换,因为代码块、链接地址和普通文本的规则并不完全相同。更稳妥的方案是先识别实体范围,再按上下文执行转义,避免把已经存在的格式再次转义。

普通文本示例:
价格为 100 \*积分\*,请勿重复提交。

链接示例:
[查看详情](https://example.com/path_(safe))

🧹 三、HTML 清洗要采用白名单策略

如果群成员可以提交带格式内容,系统就不能简单使用正则表达式删除标签。正则适合处理有限的字符替换,却很难可靠解析嵌套标签、异常属性、编码混淆和不完整的 HTML 结构。

正确做法是使用 HTML 解析器建立文档树,然后只保留业务真正需要的标签。Telegram 通知通常只需要粗体、斜体、删除线、代码、预格式文本和链接等少数元素,其他标签都应被移除或转换为纯文本。

必须重点过滤的内容

第一类是事件属性,例如点击事件、加载事件和鼠标事件;第二类是脚本协议与危险地址,例如 javascript、data 等;第三类是 style、iframe、form 等可能改变页面行为或结构的标签。

处理链接时,应先对地址进行标准化和解码,再检查协议是否属于允许范围。一般只放行 https、http 以及业务确实需要的 Telegram 链接,并拒绝空地址、控制字符和隐藏跳转。

允许标签:b、strong、i、em、u、s、del、code、pre、a

允许属性:
a[href]

拒绝内容:
事件属性、script、style、iframe、javascript:、data:

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

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

⚙️ 四、推荐的安全处理流程

第一步,确定输入来源。来自管理员模板的内容、普通群成员文本和第三方接口内容,信任等级不同,不能使用同一套放行规则。所有外部输入都应默认视为不可信。

第二步,统一内部格式。系统可以先把 Markdown 或 HTML 转换成内部实体结构,例如文本、粗体、链接、代码块等,再从实体结构生成 Telegram 消息。这样能避免在多个格式之间反复转换造成标签嵌套和转义重复。

第三步,执行白名单清洗。清洗过程中删除未知标签和危险属性,同时限制链接协议、文本长度、嵌套深度以及代码块大小。清洗后的内容还应重新序列化,不能继续拼接原始字符串。

第四步,选择最终输出模式。如果消息格式简单,可采用 HTML 模式;如果内容主要由程序生成,可使用 MarkdownV2;如果需要精确控制字符范围,建议使用 Telegram 的消息实体字段。

使用实体字段时,需要留意 Telegram 的偏移量和长度通常按照 UTF-16 代码单元计算,而不是简单按照 JavaScript 的 Unicode 字符数量计算。包含表情符号、复合字符或特殊语言文字时,必须使用经过验证的 UTF-16 计数方法。

🧪 五、上线前必须覆盖的测试场景

测试不能只验证正常的粗体和链接,还要覆盖连续特殊字符、未闭合标签、嵌套标签、超长文本、表情符号、换行、代码块和包含尖括号的普通句子。每一种输入都应检查最终显示效果和 Bot API 返回结果。

还要专门测试恶意链接、大小写混合协议、HTML 实体编码、零宽字符以及复制粘贴产生的不可见字符。对于发送失败的消息,应记录解析模式、清洗前后长度和错误类型,但不要把完整的敏感用户内容直接写入日志。

测试重点:
1. <b>粗体</b> 是否正常显示
2. 用户输入的 <script> 是否变成普通文本或被移除
3. https://example.com 是否保留
4. javascript: 协议是否被拒绝
5. 表情符号后的实体偏移是否准确
6. 未闭合标签是否不会导致整条消息失败

生产环境还应设置失败降级策略:当富文本解析失败时,可以将清洗后的内容以纯文本发送,而不是直接丢弃消息。这样既能保证通知送达,也能通过监控及时发现格式规则变化。

❓ 常见问题解答(FAQ)

Telegram HTML 模式可以使用任意网页标签吗?

不可以。Telegram 只支持有限的格式标签,浏览器中的 div、span、style 和脚本标签并不会按照完整网页规则安全执行。开发时应以 Telegram 官方支持列表为准,并主动删除未授权标签。

把所有尖括号替换掉,是否就完成安全处理?

不一定。全量替换尖括号可以降低部分标签解析问题,但会破坏合法格式,也无法处理危险链接、事件属性和后台二次渲染。安全方案应当先解析、再白名单清洗、最后按目标格式输出

为什么普通文本中出现下划线也会发送失败?

因为 MarkdownV2 会把下划线识别为格式语法的一部分,尤其是在用户名、文件名和链接参数中很常见。遇到这类内容时,应根据所在上下文进行精确转义,或改用 HTML 模式和消息实体。

群消息系统应该优先选择 MarkdownV2 还是 HTML?

没有绝对答案。模板通知和人工维护的富文本通常更适合 HTML,自动拼接的大量变量更适合经过专用转义器的 MarkdownV2,而高安全要求和复杂嵌套场景则可以优先考虑消息实体。

总的来说,可靠的群消息解析系统应当把转义、清洗、格式生成和发送降级拆分为独立步骤,并为每个环节建立测试与日志。这样不仅能减少 Telegram 消息报错,也能让富文本在机器人、网页后台和移动端之间保持一致、安全的展示效果。

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