2012-03-08 104 views
0

我很想知道是否可以使用正则表达式搜索整个DOM,然后可以基本上确定用于匹配节点的路径。换句话说,我想查找一个模式的所有匹配,可以说“你好”这个词,并且我希望至少能够识别它在DOM或者父容器中的分支。使用JavaScript反向DOM遍历

应用正则表达式匹配明显地找到了匹配,但忽略了在DOM中找到它们的位置的上下文。有没有办法覆盖这个匹配,以打印或关联匹配的位置?如果不是(假设正则表达式不会以相同的方式解析DOM树),是否有任何建议来达到预期的结果?

+2

正则表达式在这里没有帮助。你如何知道“hello”是否在元素,属性......注释中......是否是元素名称本身......没有完整的HTML解析器?在这种情况下,任何你想要使用正则表达式的东西,你都可以使用'indexOf'。任何过去的事情,我不会相信正则表达式来处理。 – cHao 2012-03-08 15:28:32

+1

(在此处插入强制性链接到http://stackoverflow.com/q/1732348/319403)。 – cHao 2012-03-08 15:38:38

回答

0

我很想知道,如果能有一个正则表达式 那么基本上可以识别用于获取到 匹配节点的路径搜索整个DOM。

那么,它理论上是possible,但非常痛苦(阅读:你不想这样做)。使用解析器解析HTML会更好。

+0

假设这全部用JavaScript完成,听起来事情可能会变得麻烦一点。有时间去书本上找出值得使用的东西。 – user1257332 2012-03-08 16:24:21

+0

@ user1257332,只需使用JS中可用的DOM并搜索文本节点? – Qtax 2012-03-08 16:26:08

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" 

//哦yeah-

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; 
     } 
    } 
}