2011-12-31 75 views
2

我想要做的是找到一個字符串中的所有匹配,然後將它們包裹在一個樣式化的span標籤中。我想出了使用遞歸的解決方案,下面的代碼:http://jsfiddle.net/Umcaf/爲什麼當我嘗試使用正則表達式測試字符串時,字符串會消失?

我遇到的問題是,它不會標示出所有實例:

function foo(node, pattern) { 
    // alert(node.nodeValue); 
    // alert(node.nodeValue + '\n' + pattern.test(node.nodeValue)); 
    if (pattern.test(node.nodeValue)) { 
     // alert(node.nodeValue); 
     var span = document.createElement('span'); 
     var text = document.createTextNode(RegExp.rightContext); 

     span.className = 'someClass'; 
     span.innerHTML = RegExp.$1; 

     node.nodeValue = RegExp.leftContext; 
     node.parentNode.insertBefore(span, node.nextSibling); 
     node.parentNode.insertBefore(text, span.nextSibling); 

     foo(text, pattern); 
    } 

    return; 
} 

在這個小提琴看到它在行動'測試'這個詞。如果你玩弄警報聲明,你會發現一些奇怪的行爲(無論如何,這對我來說很奇怪)。如果您取消註釋第一次警報,您將看到所有我想測試的正確字符串,但即使最後一個字符串中包含「test」字樣,pattern.test(node.nodeValue)也不會生成「true」。這非常令人困惑。

當然,我想出了第二條警報聲明。當使用第二條警告語句時,它會警告不正確的字符串(我的意思是它不會提醒第一個完整的字符串,並添加最後一個只包含空格的字符串),並且第一次出現'test'isn' t標記,但最後兩個是!

我對正則表達式相當陌生,但我認爲我已經足夠了解它們,直到現在。任何人都可以解釋這裏發生了什麼?

+0

@湯姆英格拉姆對此深感抱歉。我在編寫遍歷DOM的代碼時使用了它,並且從那以後我就一直使用它。在研究DOM遍歷時,將其從我遇到的某個網站上剔除。 – dunnza 2011-12-31 07:57:47

+0

沒問題刪除原來的評論cos不重要的問題 – 2011-12-31 08:01:05

回答

3

只需從您的正則表達式中刪除g,問題就消失了。

foo(node, /(test)/i); 

你在你的正則表達式中有一個全局匹配標誌。每次調用test()時,它都會將指針向前推。

你可以在這裏閱讀更多:

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/test

與EXEC(或與之結合),測試多次調用 在同一個全局正則表達式情況會提前過去 以前比賽。

+0

非常感謝你!多麼愚蠢的錯誤! – dunnza 2011-12-31 08:48:12

3

clowwindy提供瞭解決方案。

我想指出,以另一種方式來達到自己的目標(在這裏你可以保持g修改):

function bar(node, pattern) { 
    node.parentNode.innerHTML = 
     node.nodeValue.replace(pattern,'<span class="someClass">$1</span>'); 
} 

看到this jsfiddle

+0

謝謝!這似乎是一個更簡單的方法,但我認爲我需要實際創建span元素,因爲我必須將它們傳遞給它,而不是。我還需要添加事件。我仍然可以通過這種方式添加事件,但是我發現使用'addEventListener'和'attachEvent'更容易! – dunnza 2011-12-31 19:56:07

相關問題