我很想知道是否可以使用正则表达式搜索整个DOM,然后可以基本上识别用于到达匹配节点的路径。所以换句话说,我想找到一个模式的所有匹配,让我们说“hello”这个词,并且我希望至少在DOM或容器父中识别它的分支。
应用正则表达式匹配显然会找到匹配项,但忽略了保留在DOM中找到它们的位置的上下文。有没有办法覆盖此匹配以打印或关联匹配的位置?如果不是(假设正则表达式不会以相同的方式解析DOM树),是否有任何建议可以达到预期的结果?
答案 0 :(得分:1)
您可以浏览文档或某些父元素,并检查每个文本节点, 返回包含与搜索文本匹配的数据的节点数组。
如果你想以某种方式操作它们,它会为你提供一个匹配的实际节点数组。
或者,如果您只想读取每个匹配的路径,则可以返回路径而不是节点。
这个例子有三个函数 - 一个递归树,寻找文本节点, 一个跟踪从根下降的节点, 和一个匹配文本并将路径作为字符串返回到其节点。 前两个是可重复使用的,第三个是一次性的。
document.deepText= function(node, fun){
var A= [], tem;
fun= fun || function(n){
return n
};
if(node){
node= node.firstChild;
while(node!= null){
if(node.nodeType== 3){
tem= fun(node);
if(tem!= undefined) A[A.length]= tem;
}
else A= A.concat(document.deepText(node, fun));
node= node.nextSibling;
}
}
return A;
}
//返回父元素数组
document.descent= function(node, pa){
var A= [];
pa= pa || document.documentElement;
while(node){
A[A.length]= node;
if(node== pa) return A.reverse();
node= node.parentNode;
}
}
//这个返回一个数组,其中包含每个匹配节点的“路径”
//几乎所有这些都用于为路径制作字符串
//传递正则表达式或字符串
function pathstoText(rx, pa){
pa= pa || document.body;
if(!(rx instanceof RegExp)) rx= RegExp('\\b'+rx+'\\b', 'g');
var matches= document.deepText(pa, function(itm){
if(rx.test(itm.data)){
return document.descent(itm).map(function(who){
if(who.nodeType== 3) return '="'+who.data.match(rx)+'"';
var n= 1, sib= who.previousSibling, tag= who.tagName;
if(who.id) return tag+'#'+who.id;
else{
while(sib){
if(sib.tagName=== tag)++n;
sib= sib.previousSibling;
}
if(n== 1) n= '';
else n= '#'+n;
return who.tagName+n;
}
}).join('> ');
}
});
return matches.join('\n');
}
//几个例子
pathstoText('Help') //finds 'Help' on a button
HTML> BODY> DIV#evalBlock> DIV#evalBar> BUTTON#button_009> ="Help"
<强> pathstoText(/ \ bcamp [\ W] * / IG)强>
finds 'Camp,camping,etc on a page
found in 2nd paragraph of div #page3,
found 2 instances in fifth paragraph on div#page6,
and so on.
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page3> P#2>= "Camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page3> P#4>= "camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page3> P#12>= "camping"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page4> P#3>= "camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page4> P#7>= "camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page5> P#3>= "Camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page5> P#5>= "camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page5> P#7>= "camp"
HTML> BODY> DIV#bookview> DIV#pagespread> DIV#page6> P#5>= "camp,camp"
//哦,是的 -
if(!Array.prototype.map){
Array.prototype.map= function(fun, scope){
var T= this, L= T.length, A= Array(L), i= 0;
if(typeof fun== 'function'){
while(i< L){
if(i in T){
A[i]= fun.call(scope, T[i], i, T);
}
++i;
}
return A;
}
}
}
答案 1 :(得分:0)
我很想知道是否可以使用正则表达式搜索整个DOM 然后,这可以基本上确定用于到达的路径 匹配节点。
嗯,理论上它是possible,但非常痛苦(读:你不想这样做)。使用解析器解析HTML会好得多。