我仍然习惯使用正则表达式,因此我不确定如何使它正常工作。
我没有使用jQuery
,它不是当前的document
,而是从另一个来源获取的HTML作为string
。我不在乎<br />
标记之外的<p>
标记,因此我想将其解析出来。我想保留<p>
标记内的标记,以保留其换行符。
我需要更改以下内容:
<body><br /><p>hello<br />there</p><br /></body>
对此:
<body><p>hello<br />there</p></body>
我将使用什么正则表达式来完成这项工作?
编辑:更多信息,我正在尝试使用Node.js进行此服务器端。因此,我无权访问DOMParser
,但是我正在使用html-dom-parser
。我正在解析这些外部
标记,然后再将其传递给该解析器以减少生成的DOM树对象。
答案 0 :(得分:2)
您可以使用DOMPArser解析HTML内容,然后使用:not()
pseudo-class selector获取不是
Timer 0
Timer 1
Timer 2
Timer 3
Timer 4
Scheduled work 2
Started work 2
Scheduled work 0
Scheduled work 3
Ended work 2
Started work 0
Scheduled work 1
Scheduled work 4
Ended work 0
Started work 3
Ended work 3
Started work 1
Ended work 1
Started work 4
Ended work 4
标签的所有标签,然后使用>
(direct child selector)获取{{1 }}标记是它的直接子代(以避免嵌套)。
p
使用RegExp解析HTML是一个坏主意:
Using regular expressions to parse HTML: why not?
RegEx match open tags except XHTML self-contained tags
对于使用jsdom库的Node.js,它看起来很像
br
更新::如果p标记内有嵌套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)
标记的机会,请在删除前检查祖先元素。
例如:
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)
答案 1 :(得分:1)
代码<...>.querySelectorAll(':not(p) > br').forEach(ele => ele.remove())
是dangerous,因为当前者本身嵌套在非<br>
标签中时,它将删除<p>
中的所有<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 - Get closes element by selector
/** 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
而是a b
,可以在内部使用此函数forEach
elm => {
if (!elm.closest('p')) {
elm.parentNode.insertBefore(document.createTextNode(' '), elm);
elm.remove();
}
}