2012-03-08 110 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; 
     } 
    } 
}