I am trying to replace some value in the query string of the current page using JS. Eg: from开发者_如何转开发 category=Old Value
to category=New Value
.
To code looks like this:
var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/category=[^&]+&?/, 'category=' + sNewValue);
It works fine except for values that have ampersands. Luckily all the ampersands are URL encoded, so I know I should discard the amp; before the &. I think I should use lookaheads, but I don't know how. I tried this regular expression, but with no luck: /category=[^&(?!amp;)]+&?/
Thanks
Why are ampersands being encoded as & instead of %26? Or am I reading your question wrong?
If that's the way it needs to be, it might be easier for you to deal with this query string if you break it into name/value pairs first.
var pairStrings = sQueryString.split(/&(?!amp;)/gi);
Then you can work with each value without worrying if it contains an encoded & or not.
You don’t need to specify a following &
at all:
var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/(^|&)category=[^&]*/, '$1category=' + encodeURIComponent(sNewValue));
Because [^&]
does already match any character except &
. Furthermore, if category is the last parameter, there even is no following &
.
OK, I think I actually found what you need.
var sNewValue = 'category=New Value&';
sQueryString = sQueryString.replace(/category=([^&]|&)*&/, sNewValue)
You can try:
var sNewValue = 'New Value';
sQueryString = sQueryString.replace(/\bcategory=[^&]*/, 'category=' + sNewValue);
This will replace even if category is preceded by ?
as in /foo.php?category=bar
/(\bcategory=)(([^&]|&\;)*)/
This includes the many different scenarios:
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
You may want to add a global switch.
You don't get lookbehind in JavaScript regular expressions. You do get lookahead, but it is unreliable in IE, so best avoided unless you really know what you're doing.
[^&(?!amp;)]+&
yeah, this doesn't really make any sense. You can't use lookahead in a []
character group: what you're saying here is match characters that aren't &
, (
, ?
, !
, a
, m
, p
, ;
, or )
.
However you should not see &
anyway: you should be working on a plain, unencoded query string, eg. as fetched from location.search
. (If you are hacking at HTML markup in a string with regex you've got much, much bigger problems.)
If you are getting the query string from location.search
, you'll have a ?
on the front if there's any query. So you can match the beginning with either &
or ?
, and do your regex match on:
location.search.replace(
/([?&;]category=)[^&;]+/,
'$1'+encodeURIComponent(sNewValue)
);
note I have also included ;
as a possible separator as per HTML4 section B.2.2, and used encodeURIComponent
so that invalid characters like spaces and special characters like &
itself get properly URL-encoded. Also the character $
, which otherwise has special meaning in a regexp replacement string.
This is still quite messy, and doesn't cope with URL-encoded parameter names (ie c%61tegory
is a valid alternative way of saying category
) or multiple parameters with the same name. If you want to be more robust about it you could dump the regexps and do full query string parsing/reconstruction. See the functions from this answer and do:
var lookup= queryToLookup(location.search);
lookup['category']= ['New value'];
var query= lookupToQuery(lookup);
精彩评论