outerHTML.search(/\> *\</) ;// 在 outerHTML 上的正则表达式搜索有时会产生“错误”索引
Posted
技术标签:
【中文标题】outerHTML.search(/\\> *\\</) ;// 在 outerHTML 上的正则表达式搜索有时会产生“错误”索引【英文标题】:outerHTML.search(/\> *\</) ;// regex search on outerHTML yields 'wrong' index sometimesouterHTML.search(/\> *\</) ;// 在 outerHTML 上的正则表达式搜索有时会产生“错误”索引 【发布时间】:2019-11-02 05:24:24 【问题描述】:想要通过从 table 的 outerhtml 中提取来获取 table 定义的 HTML,寻找 '> 的索引
尝试了几种模式和 match() 但没有成功。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<!-- <thead> not on same line as <table> -->
<table id="t1" border="1">
<thead>
<tr> <th colspan="2">1</th><th colspan="3">22 </th></tr>
<tr> <th>1</th><th data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
</thead>
<tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
</table>
<!-- <thead> on same line as <table> -->
<table id="t2" border="1" > <thead>
<tr> <th colspan="2">1</th><th colspan="3">22 </th></tr>
<tr> <th>1</th><th data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
</thead>
<tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
</table>
<p>
<div id="out1"></div>
<p>
<div id="out2"></div>
<script>
/*****************************************
* want to get the HTML for a table definition
* by extracting <table ...> from outer html, looking
* for the index of '> whatever <'
*****************************************/
var m, t, oh, index;
/*****************************************
* does not work
*****************************************/
t = document.getElementById('t1');
oh = t.outerHTML;
index = oh.search(/\> *</); // what is wrong with regex
document.getElementById('out1').innerHTML = htmlentity(oh.substring(0, index + 1));
/*****************************************
* works
*****************************************/
t = document.getElementById('t2');
oh = t.outerHTML;
index = oh.search(/\> *\</);
document.getElementById('out2').innerHTML = htmlentity(oh.substring(0, index + 1));
function htmlentity(value)
value = value.replace(/&/gi, "&");
value = value.replace(/</gi, "<");
value = value.replace(/>/gi, ">");
value = value.replace(/"/gi, """);
value = value.replace(/'/gi, "'");
return value;
</script>
</body>
</html>
```
第一个表定义“t1”不适用于我的正则表达式。 第二个表定义“t2”确实适用于我的正则表达式。
输出:
【问题讨论】:
这个正则表达式甚至应该找到什么?为什么还要使用正则表达式而不是 DOM 方法? 我只想在表格元素的结束'>'之后找到第一个html标签的开始,第一个标签应该用' 所以...类似于table.nextSibling
?
【参考方案1】:
正则表达式有什么问题
正则表达式是解析 HTML 的错误工具。 (Obligatory link.) 它们可能是 HTML 解析器的一部分,但单独一个表达式不能胜任这项任务。
想要获取表格定义的 HTML
我会采取更直接的方法:表已经解析,所以只需克隆它,从克隆中删除所有文本节点,然后(如果您需要 HTML 而不仅仅是节点树)获取它的outerHTML
:
function extractStructure(element)
const clone = element.cloneNode(true);
removeText(clone);
return clone.outerHTML;
function removeText(element)
let child = element.firstChild;
while (child)
let next = child.nextSibling;
if (child.nodeType === 1) // Element
removeText(child);
else if (child.nodeType === 3) // Text
element.removeChild(child);
child = next;
function extractStructure(element)
const clone = element.cloneNode(true);
removeText(clone);
return clone.outerHTML;
function removeText(element)
let child = element.firstChild;
while (child)
let next = child.nextSibling;
if (child.nodeType === 1) // Element
removeText(child);
else if (child.nodeType === 3) // Text
element.removeChild(child);
child = next;
console.log(extractStructure(document.getElementById("t1")));
console.log(extractStructure(document.getElementById("t2")));
<table id="t1" border="1">
<thead>
<tr> <th colspan="2">1</th><th colspan="3">22 </th></tr>
<tr> <th>1</th><th data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
</thead>
<tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
</table>
<!-- <thead> on same line as <table> -->
<table id="t2" border="1" > <thead>
<tr> <th colspan="2">1</th><th colspan="3">22 </th></tr>
<tr> <th>1</th><th data-rotate>22</th><th data-rotate>333</th><th>4444</th><th>5555555</th></tr>
</thead>
<tr><td>aaaaaaa</td><td>bbbbbbbbb</td><td>cccccccccc</td><td>ddddd<br>ddddddd</td><td>dddddddddddd</td></tr>
</table>
【讨论】:
【参考方案2】:在t1上正在返回线
<table id="t1" border="1">
<thead>
在您的正则表达式中,您选择 /> 之后剩下的所有内容可能会贪婪吗?
试试这个index = oh.search(/\>.*?/);
代码:
const regexT = />.*?/;
t = document.getElementById('t1');
oh = t.outerHTML;
index = oh.search(regexT);
document.getElementById('out1').innerHTML = htmlentity(oh.substring(0, index + 1));
t = document.getElementById('t2');
oh = t.outerHTML;
index = oh.search(regexT);
document.getElementById('out2').innerHTML = htmlentity(oh.substring(0, index + 1));
旁注:在这种情况下,模式匹配可能不是最好的方法(参见 T.J. Crowder 的回答)
【讨论】:
为什么>
被转义了?它在正则表达式中没有特殊含义。
感谢这对我有用。我使用outerHTML,因为这是源,我知道当有一个'
如果您解决了您的问题,请不要忘记投票并接受,以便遇到相同问题的人可以使用它。别忘了看看 T.J. 的评论。
@Heinz - “我使用 outerHTML 因为这是源” 不,它不是源。它是通过遍历元素并为 DOM 中的这些元素构建 HTML 创建的新字符串。这与创建表的原始源不同(如果甚至有原始源,而不是动态创建的)。
@T.J.克劳德 - 我担心我不完全明白你在告诉我什么。对我来说,重点是,只要我在外层HTML 中找到我在左“”括号之间写的所有内容,这对我来说没问题。以上是关于outerHTML.search(/\> *\</) ;// 在 outerHTML 上的正则表达式搜索有时会产生“错误”索引的主要内容,如果未能解决你的问题,请参考以下文章