2009-11-03 63 views
2

我有一個字符串(部分HTML),我想替換字符串:-)進入設置高亮:wink:。但是這個替換不應該發生在<pre>內,而是在任何其他標籤中(或者甚至不在標籤內)發生。如何不能代替文字特定標籤內的JavaScript中

例如,我想更換

:-)<pre>:-)</pre><blockquote>:-)</blockquote> 

到:

:wink:<pre>:-)</pre><blockquote>:wink:</blockquote> 

我已經用下面的正則表達式嘗試過,但它不工作(沒有被替換):

var s = ':-)<pre>:-)</pre><blockquote>:-)</blockquote>'; 
var regex = /:\-\)(?!(^<pre>).*<\/pre>)/g; 
var r = s.replace(regex, ':wink:'); 

有人可以幫我嗎? :-)

+0

不要試圖解析與正則表達式的HTML節點; HTML不是常規的。使用合適的HTML解析器來生成DOM - 對於JavaScript,jQuery是一個理想的選擇。 – 2009-11-03 12:12:29

回答

2

這應該做到這一點: -

var src = ":-)<pre>:-)</pre><blockquote>:-)</blockquote>" 

var result = src.replace(/(<pre>(?:[^<](?!\/pre))*<\/pre>)|(\:\-\))/gi, fnCallback) 

function fnCallback(s) 
{ 
    if (s == ":-)") return ":wink:" 
    return s; 
} 

alert(result); 

它的工作原理,因爲任何pre元素將在正則表達式得到拾取的第一個選項,一旦消耗意味着任何包含:-)不能匹配因爲處理器已經超越了它。

+0

Downvoter,請說明你的理由? – AnthonyWJones 2009-11-03 12:37:56

+0

謝謝!這工作,只有輕微的故障原因是函數的定義必須是在函數調用前 - 但這是容易解決的;-) – acme 2009-11-03 12:46:54

+1

高興它解決您的問題,但我很好奇,爲什麼你覺得函數的定義需要preceed電話?它在我的測試裝置中正常工作。在執行塊之前,Javascript會在執行塊中創建所有函數定義。你在想功能表達嗎? – AnthonyWJones 2009-11-03 14:58:09

3

你可以避開地獄般的正則表達式完全如果你使用一個合適的庫如jQuery,如:

var excludeThese = ['pre']; 

// loop over all elements on page, replacing :-) with :wink: for anything 
// that is *not* a tag name in the excludeThese array 

$('* not:(' + excludeThese.join(',') + ')').each(function() { 
    $(this).html($(this).html().replace(/:\-\)/,':wink:')); 
}); 
+0

.html()返回一個字符串。因此.replace是一個正則表達式替換。 – AnthonyWJones 2009-11-03 12:28:37

+0

我總是犯這個錯誤,謝謝指出來,修正它。真的嗎?是否需要反對票? – karim79 2009-11-03 12:34:21

+0

謝謝,我已經使用原型,你知道它是如何完成的嗎? – acme 2009-11-03 12:45:20

0

嘗試 VAR正則表達式=/- (?!(^))* </PRE>)/克;

+0

可悲的是,只有當除了「:-)」之外沒有其他符號時才起作用。例如,用 「:-)

 :-)
:-)
」 失敗。 – acme 2009-11-03 12:44:10

1

只是認爲這將是值得提供的DOM解決方案:

E.g.

var div = document.createElement('div'); 
div.innerHTML = ":-)<pre>:-)</pre><blockquote>:-)</blockquote>"; 

replace(div, /:-\)/g, ":wink:", function(){ 

    // Custom filter function. 
    // Returns false for <pre> elements. 

    return this.nodeName.toLowerCase() !== 'pre'; 

}); 

div.innerHTML; // <== here's your new string! 

而這裏的replace功能:

function replace(element, regex, replacement, filter) { 

    var cur = element.firstChild; 

    if (cur) do { 

     if (!filter || filter.call(cur)) { 

      if (cur.nodeType == 1) { 
       replace(cur, regex, replacement); 
      } else { 
       cur.data = cur.data.replace(regex, replacement); 
      } 

     } 

    } while (cur = cur.nextSibling); 

} 
相關問題