有没有一种简单的方法可以将具有多个 <br/> 标签的 HTML 转换为 Javascript 中正确的周围 <p> 标签?
-
16-09-2019 - |
题
假设我有一堆 HTML,如下所示:
bla bla bla long paragraph here
<br/>
<br/>
bla bla bla more paragraph text
<br/>
<br/>
Javascript 有没有一种简单的方法可以将其转换为正确的语义 <p>
标签?例如。:
<p>
bla bla bla long paragraph here
</p>
<p>
bla bla bla more paragraph text
</p>
输出间距并不重要,理想情况下它适用于任何输入间距。
我想我可能会尝试编写一个正则表达式,但在我这样做之前,我想确保我a)避免了一个受伤的世界,b)那里没有其他东西 - 我试图做谷歌搜索,但尚未得出任何结果。
感谢您的任何建议!
解决方案
我厌倦。我敢肯定,有需要优化/调整。用了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>
其他提示
扫描每个子元素+文本封装元素的。每次遇到“BR”元素时,创建一个“P”元素,所有未决的东西附加到它。泡沫,漂洗,重复。
不要忘记删除您所搬迁到一个新的“P”元素的东西。
我已经发现这个库(prototype.js中)成为这种有用的事情。
我假设你真的不允许任何其他人
有时您需要保留单个换行符(不是全部) <br />
元素很糟糕),并且您只想将其双实例 <br />
分成段落。
这样做时我会:
- 删除所有换行符
- 将全部内容包含在一个段落中
- 代替
<br /><br />
和</p>\n<p>
- 最后,删除所有空的
<p></p>
可能已生成的元素
所以代码可能看起来像这样:
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 />
您可能真正想要的元素。
我会分几个阶段来做:
- 正则表达式:将所有 br 标签转换为换行符。
- 正则表达式:去掉所有的空白。
- 正则表达式:将多个换行符转换为单个换行符。
- 对结果使用 Array.split(' ') 。
这应该给出一个包含所有“真实”段落的数组(理论上)。然后您可以迭代它并将每一行包装在 p 标签中。
不隶属于 StackOverflow