[英]How do I remove all <br /> tags that aren't within <p> tags using regex?
我仍然习惯使用正则表达式,因此我不确定如何使它正常工作。
我没有使用jQuery
,它不是当前document
,而是从另一个来源获取html作为string
。 我不在乎<p>
标记之外的<br />
标记,因此我想将其解析出来。 我想保留<p>
标记内的内容以保留其换行符。
我需要更改以下内容:
<body><br /><p>hello<br />there</p><br /></body>
对此:
<body><p>hello<br />there</p></body>
我将使用什么正则表达式来完成这项工作?
编辑:更多信息,我正在尝试使用Node.js进行此服务器端。 因此,我无法访问DOMParser
,但是我正在使用html-dom-parser
。 我正在解析这些外部
标签,然后再将其传递给该解析器以减少生成的DOM树对象。
您可以使用DOMPArser解析HTML内容,然后使用:not()
伪类选择器获取不是p
标签的所有标签,然后使用>
(直接子选择器)获取br
标签,它是该标签的直接子标签(避免嵌套)。
let html = `<body><br /> <p>hello<br />there </p><br /></body>`; let parser = new DOMParser(); doc = parser.parseFromString(html, "text/html"); doc.querySelectorAll(':not(p) > br').forEach(ele => ele.remove()) console.log(doc.body.outerHTML)
使用RegExp解析HTML是一个坏主意:
对于使用jsdom库的Node.js,它可能看起来很像,
let html = `<body><br />
<p>hello<br />there</p><br /></body>`;
const dom = new JSDOM(html);
dom.window.document.querySelectorAll(':not(p) > br').forEach(ele => ele.remove())
console.log(dom.window.document.body.outerHTML)
更新:如果p标签内有嵌套br
标签的机会,则在删除之前检查祖先元素。
例如:
let html = `<body><br /> <p>hello<br />there<span><br/></span> </p><br /></body>`; let parser = new DOMParser(); doc = parser.parseFromString(html, "text/html"); doc.querySelectorAll(':not(p) > br').forEach(ele => { // check for any p tag in parent level if (!ele.closest('p')) ele.remove() }) console.log(doc.body.outerHTML)
根据Pranav C Balan的回答 :
代码<...>.querySelectorAll(':not(p) > br').forEach(ele => ele.remove())
很危险 ,因为当删除<p>
中的所有<br>
时,前者本身嵌套在非<p>
标记中。
let html = `<body><br> <p>hello <u>underline<br>underline</u><br>there </p><br></body>`; let parser = new DOMParser(); doc = parser.parseFromString(html, "text/html"); doc.querySelectorAll(':not(p) > br').forEach(ele => ele.remove()) console.log(doc.body.outerHTML) console.log(`This should've been: <body> <p>hello <u>underline<br>underline</u><br>there </p></body>`)
为了使其工作,我们需要获取所有<br>
元素,并检查它们是否在<p>
元素内,是否作为直接后代。 使用jQuery时,您将使用closest
方法。 我们可以使用如下所示的VanillaJS方法: PlainJS-通过选择器获取closes元素
/** source: https://plainjs.com/javascript/traversing/get-closest-element-by-selector-39/ */ // matches polyfill this.Element && function(ElementPrototype) { ElementPrototype.matches = ElementPrototype.matches || ElementPrototype.matchesSelector || ElementPrototype.webkitMatchesSelector || ElementPrototype.msMatchesSelector || function(selector) { var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1; while (nodes[++i] && nodes[i] != node); return !!nodes[i]; } }(Element.prototype); // closest polyfill this.Element && function(ElementPrototype) { ElementPrototype.closest = ElementPrototype.closest || function(selector) { var el = this; while (el.matches && !el.matches(selector)) el = el.parentNode; return el.matches ? el : null; } }(Element.prototype); let html = `<body><br> <p>hello <u>underline<br>underline</u><br>there </p><br></body>`; let parser = new DOMParser(); doc = parser.parseFromString(html, "text/html"); doc.querySelectorAll(':not(p) > br').forEach(ele => { if (!ele.closest('p')) { ele.remove() } }) console.log(doc.body.outerHTML) console.log(`That should be: <body> <p>hello <u>underline<br>underline</u><br>there </p></body>`)
如果需要在删除的<br>
位置放置空格,以防止将a<br>b
转换为ab
而不是ab
,则可以在forEach内部使用此函数
elm => {
if (!elm.closest('p')) {
elm.parentNode.insertBefore(document.createTextNode(' '), elm);
elm.remove();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.