9

我有一个 HTML 字符串,在这个例子中它看起来像

<img src="somepic.jpg" someAtrib="1" >

我正在尝试锻炼与“img”节点匹配的正则表达式,并在节点末尾应用斜杠,使其看起来像。

<img src="somepic.jpg" someAtrib="1" />

本质上,这里的最终目标是确保节点是关闭的,打开的节点在 HTML 中有效,但显然不是 XML。是否有任何正则表达式爱好者可以提供帮助?

4

4 回答 4

18

不要使用正则表达式,而是使用专用的解析器。在 JavaScript 中,使用 创建一个文档DOMParser,然后使用 序列化它XMLSerializer

var doc = new DOMParser().parseFromString('<img src="foo">', 'text/html');
var result = new XMLSerializer().serializeToString(doc);
// result:
// <html xmlns="http://www.w3.org/1999/xhtml"><head></head><body> (no line break)
// <img src="foo" /></body></html>

如果需要将它与 nodejs 后端一起使用,则必须使用xmldomnpm i xmldom.

于 2012-08-23T13:38:16.237 回答
4

您可以创建 xhtml 文档并导入/采用 html 元素。Html 字符串可以通过 HTMLElement.innerHTML 属性解析,原因。关键是使用 Document.importNode() 或 Document.adoptNode() 方法将 html 节点转换为 xhtml 节点:

var di = document.implementation;
var hd = di.createHTMLDocument();
var xd = di.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
hd.body.innerHTML = '<img>';
var img = hd.body.firstElementChild;
var xb = xd.createElement('body');
xd.documentElement.appendChild(xb);
console.log('html doc:\n' + hd.documentElement.outerHTML + '\n');
console.log('xhtml doc:\n' + xd.documentElement.outerHTML + '\n');
img = xd.importNode(img); //or xd.adoptNode(img). Now img is a xhtml element
xb.appendChild(img);
console.log('xhtml doc after import/adopt img from html:\n' + xd.documentElement.outerHTML + '\n');

输出应该是:

html doc:
<html><head></head><body><img></body></html>

xhtml doc:
<html xmlns="http://www.w3.org/1999/xhtml"><body></body></html>

xhtml doc after import/adopt img from html:
<html xmlns="http://www.w3.org/1999/xhtml"><body><img /></body></html>

Rob W 的答案在 chrome(至少 29 及以下)中不起作用,因为 DOMParser 不支持 'text/html' 类型,并且 XMLSerializer 为 chrome 中的 html 文档生成 html 语法(不是 xhtml)。

于 2013-11-07T08:57:39.230 回答
2

除了 Rob W's answer之外,您还可以使用 RegEx 提取正文内容:

var doc = new DOMParser().parseFromString('<img src="foo">', 'text/html');
var result = new XMLSerializer().serializeToString(doc);

/<body>(.*)<\/body>/im.exec(result);
result = RegExp.$1;

// result:
// <img src="foo" />

注意:parseFromString(htmlString, 'text/html');会在 IE9 中抛出错误,因为 IE9不支持text/html mimeType 。虽然适用于 IE10 和 IE11。

于 2013-11-18T20:33:30.860 回答
1

这将做得很好:

result = text.replace(/(<img\b[^<>]*[^<>\/])>/ig, "$1 />");

附录:如果(不太可能)您的代码包含包含尖括号的标记属性(这不是有效的 XML/XHTML BTW),那么这个会做得更好:

result = text.replace(/(<img\b(?:[^<>"'\/]+|'[^']*'|"[^"]*")*)>/ig, "$1 />");
于 2012-08-23T13:55:26.250 回答