Javascript RegEx替换为负向前瞻

时间:2010-09-21 14:27:03

标签: javascript regex negative-lookahead

我正在尝试使用JS替换当前页面的查询字符串中的某些值。例如:从category=Old Valuecategory=New Value。 代码看起来像这样:

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

除了具有&符号的值外,它工作正常。幸运的是,所有的&符都是URL编码的,所以我知道我应该在& 之前丢弃 amp; 。我想我应该使用前瞻,但我不知道如何。我试过这个正则表达式,但没有运气:/category=[^&(?!amp;)]+&?/

由于

6 个答案:

答案 0 :(得分:1)

您根本无需指定以下&

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

因为[^&]已匹配除&以外的任何字符。此外,如果 category 是最后一个参数,则甚至没有&

答案 1 :(得分:1)

为什么&符号被编码为& amp;而不是%26?或者我读错了你的问题?

如果这是它需要的方式,如果先将它分解为名称/值对,则可能更容易处理此查询字符串。

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

然后你可以使用每个值,而不用担心它是否包含编码和放大的值。或不。

答案 2 :(得分:0)

好的,我想我确实找到了你需要的东西。

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

答案 3 :(得分:0)

您可以尝试:

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

即使?

中的类别前面有/foo.php?category=bar,也会替换

答案 4 :(得分:0)

你不会在JavaScript正则表达式中看到后悔。你前瞻,但它在IE中是不可靠的,所以最好避免,除非你真的知道你在做什么。

[^&(?!amp;)]+&
是的,这没有任何意义。您无法在[]字符组中使用前瞻:您在此处所说的不是&(?,{{1 }},!amp;

但是你不应该看到):你应该处理一个简单的,未编码的查询字符串,例如。从&获取。 (如果你在使用正则表达式的字符串中破解HTML标记,那么你会遇到更大,更大的问题。)

如果您 location.search获取查询字符串,如果有任何查询,您前面会有location.search。因此,您可以将开头与?&匹配,并执行正则表达式匹配:

?

注意我还根据HTML4 B.2.2部分将location.search.replace( /([?&;]category=)[^&;]+/, '$1'+encodeURIComponent(sNewValue) ); 作为可能的分隔符,并使用了;,以便像encodeURIComponent这样的空格和特殊字符等无效字符可以正常使用URL编码。也是字符&,否则在regexp替换字符串中具有特殊含义。

这仍然非常混乱,并且不处理URL编码的参数名称(即$是一种有效的替代方式,即c%61tegory}或多个具有相同名称的参数。如果你想对它更加健壮,你可以转储正则表达式并进行完整的查询字符串解析/重建。查看this answer中的函数并执行:

category

答案 5 :(得分: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

您可能想要添加全局开关。