【问题标题】:Tokenize HTML string in JavaScript [duplicate]在 JavaScript 中标记 HTML 字符串 [重复]
【发布时间】:2017-12-27 22:21:10
【问题描述】:

我想拆分一个如下所示的字符串:

This is <strong>a</strong> test <a href="#test">link</a> and <br /> line. break

使用 JavaScript 进入以下内容:

[
    'This',
    'is',
    '<strong>a</strong>',
    'test',
    '<a href="#test">link</a>',
    '<br />',
    'line.',
]

我尝试在空格和&lt; &gt; 上进行拆分,但这显然不适用于stronga 之类的标签。我不确定如何编写一个不在 HTML 标记中拆分的正则表达式。我也尝试使用 jQuery children(),但它不提取纯文本,只提取 html 标签。任何帮助都会很棒。

【问题讨论】:

  • 这比看起来更复杂。解析 HTML 很困难。
  • 这不就是str.split(" ");吗?
  • 没有一个简单的 reg exp 可以做到这一点......
  • @eLRuLL 这会将 br 放在两个索引上
  • 我无法想象你会这样做的原因,但如果它是为了某种用户输入(cmets、论坛帖子等),创建你的会更容易(也更安全)自己的降价风格,而不是深入研究标记化 HTML 的领域。

标签: javascript html regex


【解决方案1】:

如果代码在浏览器中执行,使用浏览器的解析器将字符串分成文本和标签组件可能会提供另一种解决方法:

var text = 'This is <strong>a</strong> <a href="#test">link</a> and <br /> line. break'

function splitHTML( text) {
    var parts = [];
    var div = document.createElement('DIV');
    div.innerHTML = text;
    div.normalize();
    for( var node = div.firstChild; node; node=node.nextSibling) {
         if( node.nodeType == Node.TEXT_NODE) {
             parts.push.apply( parts, node.textContent.split(" "));
         }
         else if( node.nodeType == Node.ELEMENT_NODE) {
             parts.push( node.outerHTML);
         }
    }
    return parts;
}
console.log( splitHTML( text));

注意将由空格分隔的文本节点添加到结果中的行

 parts.push.apply( parts, node.textContent.split(" "));

用于演示,需要进一步工作以防止输出中的零长度字符串用于文本和 html 标记元素之间的空格。此外,html 标签是从 DOM 元素重建的,可能与输入不完全匹配:在这种情况下,XHTML 标签&lt;br \&gt; 作为&lt;br&gt; HTML 标签(不带结束标签)返回。

一般的想法是通过使用浏览器解析它来使用正则表达式来绕过解析html。可以理解,这可能适合也可能不适合目标环境和全套要求。

【讨论】:

    【解决方案2】:

    要实现你想要的,你需要考虑这个:

    规则 1) 如果还没有出现“

    规则 2)如果出现“”或“/”..">”并在其后拆分,然后再次从规则 1 开始。

    在遍历字符串时应用这些规则,你就很成功了。

    使这个递归,即像

    这样的嵌套标签
    <div>
        <p>Hi</p>
        <p>Bye</p>
    </div>
    

    更难。如上所述,实际上解析一个 html 树是非常复杂的。

    【讨论】:

      【解决方案3】:

      试试这个:

      #(?:(?!&lt;)[^&lt;&gt;]+(?!&gt;))|(?:&lt;(?=[^/&gt;]+\/&gt;).*\/&gt;)|(?:&lt;([^\s]+).*&gt;.*(?=&lt;\/\1&gt;)&lt;\/\1&gt;)#g

      它应该在简单的情况下工作,我现在能想到的。 使用捕获的组找出TAG名称,然后递归执行块元素为div

      【讨论】:

        猜你喜欢
        • 2016-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-17
        • 1970-01-01
        • 2018-07-23
        • 2012-09-19
        • 1970-01-01
        相关资源
        最近更新 更多