繁体   English   中英

如何删除所有 <br /> 不在标签内 <p> 标签使用正则表达式?

[英]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是一个坏主意:

使用正则表达式解析HTML:为什么不呢?

RegEx匹配XHTML自包含标签以外的打开标签


对于使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM