有没有一种简单的方法可以将带有多个<br/>标签的HTML转换为Javascript中适当的<p>标签?</p>

时间:2009-08-13 23:31:03

标签: javascript html semantics semantic-markup

假设我有一堆HTML如下:

bla bla bla long paragraph here
<br/>
<br/>
bla bla bla more paragraph text
<br/>
<br/>

是否有一种简单的方法可以将Javascript转换为正确的语义<p>标签? E.g:

<p>
  bla bla bla long paragraph here
</p>
<p>
  bla bla bla more paragraph text
</p>

输出间距并不重要,理想情况下它可以用于任何输入间距。

我想我可能会尝试制作一个正则表达式,但在我这样做之前,我想确保我是a)避免受伤的世界b)那里没有别的东西 - 我会我试图进行谷歌搜索,但尚未提出任何建议。

感谢您的任何建议!

4 个答案:

答案 0 :(得分:6)

我很无聊。我确信需要进行优化/调整。使用一点点jQuery来实现它的魔力。在FF3工作。你的问题的答案是,有一种非常“简单”的方式:)

$(function() {
  $.fn.pmaker = function() {
    var brs = 0;
    var nodes = [];

    function makeP()
    {
      // only bother doing this if we have nodes to stick into a P
      if (nodes.length) {
        var p = $("<p/>");
        p.insertBefore(nodes[0]);  // insert a new P before the content
        p.append(nodes); // add the children        
        nodes = [];
      }
      brs=0;
    }

    this.contents().each(function() {    
      if (this.nodeType == 3) // text node 
      {
        // if the text has non whitespace - reset the BR counter
        if (/\S+/.test(this.data)) {
          nodes.push(this);
          brs = 0;
        }
      } else if (this.nodeType == 1) {
        if (/br/i.test(this.tagName)) {
          if (++brs == 2) {
            $(this).remove(); // remove this BR from the dom
            $(nodes.pop()).remove(); // delete the previous BR from the array and the DOM
            makeP();
          } else {
            nodes.push(this);
          }
        } else if (/^(?:p)$/i.test(this.tagName)) {
          // these tags for the P break but dont scan within
          makeP();
        } else if (/^(?:div)$/i.test(this.tagName)) {
          // force a P break and scan within
          makeP();
          $(this).pmaker();
        } else {
          brs = 0; // some other tag - reset brs.
          nodes.push(this); // add the node 
          // specific nodes to not peek inside of - inline tags
          if (!(/^(?:b|i|strong|em|span|u)$/i.test(this.tagName))) {
            $(this).pmaker(); // peek inside for P needs            
          }
        } 
      } 
    });
    while ((brs--)>0) { // remove any extra BR's at the end
      $(nodes.pop()).remove();
    }
    makeP();
    return this;
  };

  // run it against something:
  $(function(){ 
    $("#worker").pmaker();
  });

这是我测试的html部分:

<div id="worker">
bla bla bla long <b>paragraph</b> here
<br/>
<br/>
bla bla bla more paragraph text
<br/>
<br/>
this text should end up in a P
<div class='test'>
  and so should this
  <br/>
  <br/>
  and this<br/>without breaking at the single BR
</div>
and then we have the a "buggy" clause
<p>
  fear the real P!
</p>
and a trailing br<br/>
</div>

结果:

<div id="worker"><p>
bla bla bla long <b>paragraph</b> here
</p>
<p>
bla bla bla more paragraph text
</p>
<p>
this text should end up in a P
</p><div class="test"><p>
  and so should this
  </p>
  <p>
  and this<br/>without breaking at the single BR
</p></div><p>
and then we have the a "buggy" clause
</p><p>
  fear the real P!
</p><p>
and a trailing br</p>
</div>

答案 1 :(得分:4)

扫描每个子元素+封闭元素的文本。每次遇到“br”元素时,都要创建一个“p”元素,并将所有待处理的内容附加到其中。泡沫,冲洗,重复。

不要忘记删除您要重新定位到新“p”元素的内容。

我发现this library (prototype.js)对这类事情有用。

答案 2 :(得分:4)

我假设你并没有真正允许任何其他人 有时您需要保留单个换行符(并非所有<br />元素都不好),并且您只想将<br />的双实例转换为分段符。

这样做我会:

  1. 删除所有换行符
  2. 将所有内容整理成段落
  3. <br /><br />替换为</p>\n<p>
  4. 最后,删除可能已生成的所有空<p></p>元素
  5. 因此代码看起来像:

    var ConvertToParagraphs = function(text) {
        var lineBreaksRemoved = text.replace(/\n/g, "");
        var wrappedInParagraphs = "<p>" + lineBreaksRemoved + "</p>";
        var brsRemoved = wrappedInParagraphs.replace(/<br[^>]*>[\s]*<br[^>]*>/gi, "</p>\n<p>");
        var emptyParagraphsRemoved = brsRemoved.replace(/<p><\/p>/g, "");
        return emptyParagraphsRemoved;
    }
    

    注意:我一直非常详细地展示流程,当然你会简化它。

    这会变成你的样本:

    bla bla bla long paragraph here
    <br/>
    <br/>
    bla bla bla more paragraph text
    <br/>
    <br/>
    

    分为:

    <p>bla bla bla long paragraph here</p>
    <p>bla bla bla more paragraph text</p>
    

    但它不会删除您可能实际需要的任何<br />元素。

答案 3 :(得分:0)

我会分几个阶段完成:

  1. RegExp:将所有br-tag转换为换行符。
  2. RegExp:去除所有空白区域。
  3. RegExp:将多个换行符转换为单个换行符。
  4. 对结果使用Array.split('\ n')。
  5. 那应该给出一个包含所有'真实'段落的数组(理论上)。然后你可以迭代它并将每一行包装在p-tags中。