Javascript RegExp替换为负前瞻
我试图用JS替换当前页面查询字符串中的一些值。例如:从Javascript RegExp替换为负前瞻,javascript,regex,negative-lookahead,Javascript,Regex,Negative Lookahead,我试图用JS替换当前页面查询字符串中的一些值。例如:从category=旧值到category=新值。 编写代码的步骤如下所示: var sNewValue = 'New Value'; sQueryString = sQueryString.replace(/category=[^&]+&?/, 'category=' + sNewValue); 它可以正常工作,但有符号的值除外。幸运的是,所有的符号都是URL编码的,所以我知道我应该放弃amp在和之前。我想我应该用looka
category=旧值
到category=新值
。
编写代码的步骤如下所示:
var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/category=[^&]+&?/, 'category=' + sNewValue);
它可以正常工作,但有符号的值除外。幸运的是,所有的符号都是URL编码的,所以我知道我应该放弃amp在和之前。我想我应该用lookaheads,但我不知道怎么用。我尝试了这个正则表达式,但没有成功:/category=[^&(!amp;)]+&?/
谢谢好的,我想我已经找到你需要的了
var sNewValue = 'category=New Value&';
sQueryString = sQueryString.replace(/category=([^&]|&)*&/, sNewValue)
您根本不需要指定以下
&
:
var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/(^|&)category=[^&]*/, '$1category=' + encodeURIComponent(sNewValue));
因为
[^&]
已经匹配了除&
之外的任何字符。此外,如果category是最后一个参数,那么甚至没有下面的&
为什么要将安培数编码为&;而不是%26?还是我看错了你的问题
如果需要这样做,那么如果首先将查询字符串分解为名称/值对,您可能会更容易处理该查询字符串
var pairStrings = sQueryString.split(/&(?!amp;)/gi);
然后,您就可以处理每个值,而不用担心它是否包含编码的&值。您可以尝试:
var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/\bcategory=[^&]*/, 'category=' + sNewValue);
即使category前面加了
?
,这也会被替换,就像在/foo.php?category=bar
中一样,您不会在JavaScript正则表达式中看到后面的内容。你确实可以向前看,但在IE中它是不可靠的,所以最好避免,除非你真的知道自己在做什么
[^&(?!amp;)]+&
是的,这没有任何意义。您不能在[]
字符组中使用前瞻:您在这里说的是匹配不是&
,(
,?
,!
,a
,m
,p
,;
或)
但是,您不应该看到&代码>无论如何:您应该处理一个普通的、未编码的查询字符串,例如,从location.search
获取的字符串。(如果你正在用正则表达式破解字符串中的HTML标记,你会遇到很多更大的问题。)
如果您是从location.search
获取查询字符串,如果有任何查询,则前面会有一个?
。因此,您可以将开头与&
或?
匹配,并在以下位置执行正则表达式匹配:
location.search.replace(
/([?&;]category=)[^&;]+/,
'$1'+encodeURIComponent(sNewValue)
);
注:我还包括根据HTML4第B.2.2节,代码>作为可能的分隔符,并使用encodeURIComponent
,以便对无效字符(如空格)和特殊字符(如&
本身)进行正确的URL编码。还有字符$
,它在regexp替换字符串中有特殊含义
这仍然非常混乱,无法处理URL编码的参数名称(即c%61tegory
是表示类别
的有效替代方式)或具有相同名称的多个参数。如果您想更加健壮,可以转储regexp并执行完整的查询字符串解析/重构。请参阅和中的函数:
/(\bcategory=)([^&]|和\*)/
这包括许多不同的场景:
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=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s2.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s3.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s4.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s5.replace(/(\bcategory=)(([^&]|&\;)*)/, "$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
您可能需要添加一个全局开关。如果该值为'category=New&;Value&cat2=blah“这将捕获”category=New&“而不是”category=New&;我认为他想要的是Value&。如果Value有一个编码的&;这就是我认为他试图解决的问题。@adam0101:uri对HTML字符引用一无所知,因为uri不是HTML。和
分隔名称/值对(请参阅)。这意味着category=New&;Value&cat2=blah
产生三个名称/值对:类别有新的,amp;值没有值,cat2有blah
。这可能是,但是如果他正在使用的查询字符串中有编码为&;如果可能的话,他需要的不是%26,而是可以处理该问题的代码,或者修复查询字符串的创建方式。谢谢您的回答。对我来说,似乎最简单的解决办法是首先更换&;与%26。然后做我的处理。
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=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s2.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s3.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s4.replace(/(\bcategory=)(([^&]|&\;)*)/, "$1" + n) );
console.log( s5.replace(/(\bcategory=)(([^&]|&\;)*)/, "$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