2010-09-21 51 views
0

我試圖用JS替換當前頁面的查詢字符串中的某個值。例如:從category=Old Valuecategory=New Value。 代碼看起來是這樣的:Javascript RegExp替換爲負向預覽

var sNewValue = 'New Value'; 
sQueryString = sQueryString.replace(/category=[^&]+&?/, 'category=' + sNewValue); 

它的工作原理,除了有與符號價值的罰款。幸運的是所有的&符號都是URL編碼的,所以我知道我應該放棄amp;之前的&。我想我應該使用lookaheads,但我不知道如何。我想這正則表達式,但沒有運氣:/category=[^&(?!amp;)]+&?/

感謝

回答

1

爲什麼將&符號編碼爲& amp;而不是%26?或者我讀錯了你的問題?

如果這是它需要的方式,如果先將它分解爲名稱/值對,處理這個查詢字符串可能會更容易。

var pairStrings = sQueryString.split(/&(?!amp;)/gi); 

然後你就可以用每個值工作,而不用擔心是否包含編碼&與否。

+0

謝謝你的回答。對我來說,最簡單的解決方案似乎是先用**%26 **替換** & **。然後做我的處理。 – bogdanvursu 2010-09-22 06:55:33

0

OK,我想,我居然找到你所需要的。

var sNewValue = 'category=New Value&'; 
sQueryString = sQueryString.replace(/category=([^&]|&)*&/, sNewValue) 
+0

如果值爲'category = New & Value&cat2 = blah',這將捕獲'category = New&'而不是'category = New & Value&'這是我認爲他想要的。 – adam0101 2010-09-21 14:36:25

1

你並不需要指定以下&都:

var sNewValue = 'New Value'; 
sQueryString = sQueryString.replace(/(^|&)category=[^&]*/, '$1category=' + encodeURIComponent(sNewValue)); 

因爲[^&]除了&也已經匹配任何字符。此外,如果類別是最後一個參數,那麼甚至沒有以下&

+0

這是行不通的,如果價值有編碼&這是我認爲他正試圖解決。 – adam0101 2010-09-21 14:48:34

+1

@ adam0101:由於URI不是HTML,因此URI不知道任何關於HTML字符引用的內容。 '&'分隔名稱/值對(見http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1)。這意味着'category = New & Value&cat2 = blah'產生三個名稱/值對:* category *具有'New',* amp; Value *沒有值,* cat2 *具有'blah'。 – Gumbo 2010-09-21 14:55:17

+0

這可能是,但是如果他正在處理的查詢字符串具有編碼爲&而不是%26的符號,那麼他將需要能夠處理該問題的代碼,否則將修復如何創建查詢字符串(如果可能)。 – adam0101 2010-09-21 15:40:11

0

你可以試試:

var sNewValue = 'New Value'; 
sQueryString = sQueryString.replace(/\bcategory=[^&]*/, 'category=' + sNewValue); 

這將取代即使類別由?之前爲/foo.php?category=bar

0

你不會在JavaScript正則表達式得到回顧後。你的得到了前瞻,但它在IE中是不可靠的,所以最好避免,除非你真的知道你在做什麼。

[^&(?!amp;)]+& 

是的,這沒有任何意義。你不能在[]字符組使用前瞻:你的意思是在這裏比賽字符不是&(?!amp;,或)

但是,您不應該看到&無論如何:您應該使用一個普通的,未編碼的查詢字符串,例如。從location.search獲取。 (如果你用正則表達式在一個字符串中對HTML標記進行黑客攻擊,你會遇到很多更大的問題。)

如果你location.search得到查詢字符串,你就會有一個在前面?如果有任何查詢。所以,你可以搭配任何&?開始,做你的正則表達式匹配:

location.search.replace(
    /([?&;]category=)[^&;]+/, 
    '$1'+encodeURIComponent(sNewValue) 
); 

注意到我也包括;作爲一種可能的分離按照HTML4部分B.2.2,並用encodeURIComponent,使無效的像空格和特殊字符如&本身得到正確的URL編碼。字符$,否則在正則表達式替換字符串中具有特殊含義。

這仍然是相當混亂,並沒有處理URL編碼的參數名稱(即c%61tegory是一種有效的替代方式說)或多個參數具有相同的名稱。如果你想更強大的話,你可以轉儲正則表達式並做完整的查詢字符串解析/重建。查看功能從this answer做:

var lookup= queryToLookup(location.search); 
lookup['category']= ['New value']; 
var query= lookupToQuery(lookup); 
0

/(\bcategory=)(([^&]|&amp\;)*)/

這包括許多不同的情況:

var s1 = 'http://www.foobar.com/?category=old&foo=bar'; 
    var s2 = 'http://www.foobar.com/?category=old'; 
    var s3 = 'http://www.foobar.com/?foo=bar&category=old'; 
    var s4 = 'http://www.foobar.com/?foo=bar&category=old&value'; 
    var s5 = 'http://www.foobar.com/?foo=bar&category=old&value&bar=foo'; 

    var n = 'NewVal'; 

    console.log(s1.replace(/(\bcategory=)(([^&]|&amp\;)*)/, "$1" + n)); 
    console.log(s2.replace(/(\bcategory=)(([^&]|&amp\;)*)/, "$1" + n)); 
    console.log(s3.replace(/(\bcategory=)(([^&]|&amp\;)*)/, "$1" + n)); 
    console.log(s4.replace(/(\bcategory=)(([^&]|&amp\;)*)/, "$1" + n)); 
    console.log(s5.replace(/(\bcategory=)(([^&]|&amp\;)*)/, "$1" + n)); 

    // s1 output: http://www.foobar.com/?category=NewVal&foo=bar 
    // s2 output: http://www.foobar.com/?category=NewVal 
    // s3 output: http://www.foobar.com/?foo=bar&category=NewVal 
    // s4 output: http://www.foobar.com/?foo=bar&category=NewVal 
    // s5 output: http://www.foobar.com/?foo=bar&category=NewVal&bar=foo 

您可能需要添加一個全球性的開關。

+0

很好的例子。 – 2010-09-21 15:42:38