首页 > 解决方案 > 包装列表项标签

  • 带着

    问题描述

    我正在尝试构建一个用 HTML 标记文本而无需手动执行的工具。

    目前,该工具将文本复制到富文本编辑器中,并在使用一堆 .replace 正则表达式模式清理一些常见问题后输出 HTML。

    我似乎无法解决的一个问题是转换从 MS Word 粘贴的列表。这是 MS word 中的样子:

    <p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lorem Ipsum dolores.</p>
    <p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lorem Ipsum dolores.</p>
    <p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lorem Ipsum dolores.</p>
    <p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Lorem Ipsum dolores.</p>
    

    我能够通过正则表达式对其进行转换,以便每个都包含一个列表项,但我无法弄清楚如何将列表项包装在无序列表标签中。

    例如,我想改变

    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    

    进入

    <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    </ul>
    

    我无法匹配正则表达式。这是我正在使用的:

    .replace(/(?<!<\/li>)<li>/, "<ul><li>")
    

    标签: javascriptregex

    解决方案


    带有 HTML 的 RegExps 通常是一个坏主意。我个人会使用 DOMParser 并使用 DOM 方法更改 HTML。如果您只有一组 lis,那么就像选择它们并将它们附加到 UL 一样简单。

    var str = `
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    `
    var parser = new DOMParser();
    var doc = parser.parseFromString(str, 'text/html')
    var body = doc.querySelector('body')
    var lis = doc.querySelectorAll('li')
    var ul = document.createElement('ul')
    body.insertBefore(ul, lis[0])
    lis.forEach(li => ul.appendChild(li))
    console.log(doc.querySelector('body').innerHTML)

    如果可以有多个列表,则需要找到分组并添加多个 ul。

    var str = `
    <li></li>
    <li></li>
    <p></p>
    <li></li>
    <li></li>
    <li></li>
    <p></p>
    <li></li>
    `
    var parser = new DOMParser();
    var doc = parser.parseFromString(str, 'text/html')
    var body = doc.querySelector('body')
    var lis = doc.querySelectorAll('li')
    var groups = Array.from(lis).reduce((groups, li, index, arr) => {
      if (index === 0 || li.previousElementSibling !== arr[index-1]) {
        groups.push([])
      }
      groups[groups.length-1].push(li)
      return groups
    }, [])
    groups.forEach(lis => {
      var ul = document.createElement('ul')
      body.insertBefore(ul, lis[0])
      lis.forEach(li => ul.appendChild(li))
    })
    console.log(doc.querySelector('body').innerHTML)


    推荐阅读