You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

聊天网站文本自动转HTML列表与表格功能实现求助

修复文本转HTML列表/表格的实现方案

原代码存在的核心问题

  • 未支持有序列表(包括用户提到的1. Pizza2. Burgers这种无换行的连续编号文本)
  • 列表标签判断逻辑错误:用全局查找<ul>来决定是否开启标签,会把多个独立列表合并成一个
  • 表格未识别分隔线行(如|---|---|),会错误转换成表头或数据单元格
  • 未处理无换行的连续列表项
  • 普通文本换行处理不够严谨,可能出现多余的<br>标签

修复后的完整代码

function convertTextToHTML(text) {
  // 先拆分连在一起的列表项(比如1. Pizza2. Burgers)为独立行
  text = text.replace(/(\d+\.\s?[^0-9]+)(?=\d+\.)/g, "$1\n");
  text = text.replace(/(\*\s?[^*]+)(?=\*)/g, "$1\n");

  const lines = text.split("\n");
  let result = "";
  let currentListType = null; // 跟踪当前列表类型:'ul' 或 'ol'
  let isTable = false;
  let tableHeaders = [];
  let isTableHeaderSet = false;

  for (let line of lines) {
    line = line.trim();
    if (!line) {
      // 处理空行:先关闭当前的列表/表格,再添加换行
      if (currentListType) {
        result += `</${currentListType}>`;
        currentListType = null;
      }
      if (isTable) {
        result += "</tbody></table>";
        isTable = false;
        tableHeaders = [];
        isTableHeaderSet = false;
      }
      result += "<br>";
      continue;
    }

    // 处理表格:匹配|开头结尾的行
    if (line.startsWith("|") && line.endsWith("|")) {
      // 先关闭当前的列表
      if (currentListType) {
        result += `</${currentListType}>`;
        currentListType = null;
      }

      const cells = line.split("|").slice(1, -1).map(cell => cell.trim());
      // 判断是否是表格分隔线(全由-或:组成)
      const isSeparator = cells.every(cell => /^[-:]+$/.test(cell));
      if (isSeparator) {
        isTableHeaderSet = true;
        continue;
      }

      isTable = true;
      if (!isTableHeaderSet && tableHeaders.length === 0) {
        // 生成表头
        tableHeaders = cells.map(cell => `<th>${cell}</th>`);
        result += "<table border='1'><thead><tr>" + tableHeaders.join("") + "</tr></thead><tbody>";
      } else {
        // 生成数据行
        const tableCells = cells.map(cell => `<td>${cell}</td>`);
        result += "<tr>" + tableCells.join("") + "</tr>";
      }
    } 
    // 处理无序列表:*开头的行
    else if (line.startsWith("*")) {
      // 先关闭当前的表格
      if (isTable) {
        result += "</tbody></table>";
        isTable = false;
        tableHeaders = [];
        isTableHeaderSet = false;
      }

      const content = line.slice(1).trim();
      if (!currentListType || currentListType !== 'ul') {
        // 开启新的无序列表
        if (currentListType) result += `</${currentListType}>`;
        currentListType = 'ul';
        result += "<ul>";
      }
      result += `<li>${content}</li>`;
    }
    // 处理有序列表:数字+.开头的行
    else if (/^\d+\./.test(line)) {
      // 先关闭当前的表格
      if (isTable) {
        result += "</tbody></table>";
        isTable = false;
        tableHeaders = [];
        isTableHeaderSet = false;
      }

      const content = line.replace(/^\d+\.\s?/, "").trim();
      if (!currentListType || currentListType !== 'ol') {
        // 开启新的有序列表
        if (currentListType) result += `</${currentListType}>`;
        currentListType = 'ol';
        result += "<ol>";
      }
      result += `<li>${content}</li>`;
    }
    // 处理普通文本
    else {
      // 先关闭当前的列表/表格
      if (currentListType) {
        result += `</${currentListType}>`;
        currentListType = null;
      }
      if (isTable) {
        result += "</tbody></table>";
        isTable = false;
        tableHeaders = [];
        isTableHeaderSet = false;
      }
      result += `${line}<br>`;
    }
  }

  // 循环结束后关闭未闭合的标签
  if (currentListType) result += `</${currentListType}>`;
  if (isTable) result += "</tbody></table>";

  return result;
}

关键修复说明

  1. 拆分连续列表项:用正则把无换行的连续编号文本(如1. Pizza2. Burgers)拆分成独立行,保证列表项能被正确识别
  2. 支持有序列表:通过正则匹配数字+.开头的行,自动生成<ol>标签
  3. 修复列表逻辑:用currentListType跟踪当前列表类型,避免多个独立列表被错误合并
  4. 表格分隔线处理:识别|---|---|这种分隔线,跳过不转换,同时标记表头已就绪
  5. 空行处理:遇到空行时自动关闭当前的列表/表格,保证HTML结构正确
  6. 严谨的标签闭合:循环结束后检查并关闭所有未闭合的标签,避免结构错误

测试示例

输入文本:

今天想吃这些:
1. Pizza2. Burgers
3. Fries

* 可乐
* 雪碧

| 食物 | 价格 |
|------|------|
| Pizza | $10 |
| Burger | $8 |

以上就是全部啦!

转换后的HTML片段:

今天想吃这些:<br>
<ol>
<li>Pizza</li>
<li>Burgers</li>
<li>Fries</li>
</ol>
<br>
<ul>
<li>可乐</li>
<li>雪碧</li>
</ul>
<br>
<table border='1'><thead><tr><th>食物</th><th>价格</th></tr></thead><tbody>
<tr><td>Pizza</td><td>$10</td></tr>
<tr><td>Burger</td><td>$8</td></tr>
</tbody></table>
<br>
以上就是全部啦!<br>

内容的提问来源于stack exchange,提问作者Erzen Krasniqi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:24:55