,我用小程序对接了腾讯的智能体,就是咱们目前不是流式输出的markdownn格式嘛,我们是用小程序对接的,把他转成html格式了,但是因为是流式输入,我们转的时候,可能会出现只转了一部分,比如1、【**张】2,【三\】3、【n他是比较厉害的】
/**
* 轻量级 Markdown 转 HTML 函数
* 兼容特性:标题(h1-h6)、换行(<br>)、段落(<p>)、粗体(** **)、无序列表(- )、有序列表(1. )、对齐(<!-- align: left/center/right -->)
* @param {string} md - 输入的 Markdown 文本
* @returns {string} 转换后的 HTML 字符串
*/
MarkToHtml(md) {
// 步骤1:补全不完整的 ** 闭合(核心新增逻辑)
// 先处理 "开头有**但结尾没有":匹配 ** 开头,且后面没有成对 ** 的内容
md = md.replace(/\*\*(.*?)(?=\n\n|<!-- align: |$)(?!\*\*)/g, (_, content) => {
return content ? `<strong>${content}</strong>` : '';
});
// 再处理 "结尾有**但开头没有":匹配 前面没有成对 **,且结尾是**的内容
md = md.replace(/(?<!\*\*)(.*?)\*\*(?=\n\n|<!-- align: |$)/g, (_, content) => {
return content ? `<strong>${content}</strong>` : '';
});
// 步骤2:处理对齐区块
md = md.replace(/<!-- align: (left|center|right) -->\s*([\s\S]*?)(?=\n\n|<!-- align: |$)/g, (_, align, content) => {
return `<div style="text-align: ${align};">${content}</div>`;
});
// 步骤3:处理完整的 ** 粗体(兼容原有正确格式)
md = md.replace(/\*\*([\s\S]*?)\*\*/g, '<strong>$1</strong>');
// 步骤4:拆分区块并处理
const blocks = md.split(/\n{2,}/).map(block => block.trim()).filter(Boolean);
let html = '';
for (const block of blocks) {
// 标题
if (/^#{1,6}\s+/.test(block)) {
html += block.replace(/^(#{1,6})\s+(.*)$/, (_, hashes, text) => `<h${hashes.length}>${text}</h${hashes.length}>`) + '\n';
}
// 无序列表
else if (/^- /.test(block)) {
const items = block.replace(/^- (.*)$/gm, '<li>$1</li>');
html += `<ul>${items}</ul>\n`;
}
// 有序列表
else if (/^\d+\. /.test(block)) {
const items = block.replace(/^\d+\. (.*)$/gm, '<li>$1</li>');
html += `<ol>${items}</ol>\n`;
}
// 普通内容 → span标签
else {
html += `<span>${block}</span>\n`;
}
}
// 步骤5:换行转<br>
html = html.replace(/<span>([\s\S]*?)<\/span>/g, (_, content) => {
return `<span>${content.replace(/\n/g, '<br>')}</span>`;
});
// 步骤6:清理空标签和多余 **(容错处理)
html = html.replace(/<(span|li|ul|ol)>\s*<br>\s*<\/\1>/g, '');
html = html.replace(/<(span|li)>\s*<\/\1>/g, '');
html = html.replace(/<strong>\s*<\/strong>/g, ''); // 清理空的strong标签
html = html.replace(/\*\*/g, ''); // 清理残留的未匹配**
return html.trim();
}
