Search and replace specific query string parameter value in javascript - javascript

I have a string which is something like this :
a_href= "www.google.com/test_ref=abc";
I need to search for test_ref=abc in thisabove strinng and replace it with new value
var updated_test_ref = "xyz";
a_href ="www.google.com/test_ref=updated_test_ref"
i.e
www.google.com/test_ref=xyz.
How can we do this ?
EDIT:
test_ref value can be a URL link in itself something like http://google.com?param1=test1&param2=test2. I need to capture complete value not till first &.

a_href = a_href.replace(/(test_ref=)[^\&]+/, '$1' + updated_test_ref);

Based on this discussion I have fixed the Chris function (problem with regex string!)
function updateUrlParameter(url, param, value){
var regex = new RegExp('('+param+'=)[^\&]+');
return url.replace( regex , '$1' + value);
}

Based on this discussion I have created a references function. enjoy
updateUrlParameter(url, param, value){
var regex = new RegExp("/([?|&]" + param + "=)[^\&]+/");
return url.replace(regex, '$1' + value);
}

I was searching for this solution for few hours and finally stumbled upon this question. I have tried all the solutions here. But there is still an issue while replacing specific param value in url.
Lets take a sample url like
http://google.com?param1=test1&param2=test2&anotherparam1=test3
and the updated url should be like
http://google.com?param1=newtest&param2=test2&anotherparam1=test3, where value of param1 is changed.
In this case, as #Panthro has pointed out, adding [?|&] before the querying string ensures that anotherparam1 is not replaced. But this solution also adds the '?' or '&' character to the matching string. So while replacing the matched characters, the '?' or '&' will also get replaced. You will not know exactly which character is replaced so you cannot append that character as well.
The solution is to match '?' or '&' as preceding characters only.
I have re-written the function of #Chris, fixing the issue with string and have added case insensitive argument.
updateUrlParameter(url, param, value){
var regex = new RegExp('(?<=[?|&])(' + param + '=)[^\&]+', 'i');
// return url.replace(regex, param + '=$1' + value);
return url.replace(regex, param + '=' + value);
}
Here (?<=[?|&]) means, the regex will match '?' or '&' char and will take the string that occurs after the specified character (looks behind the character). That means only param1=test1 substring will be matched and replaced.

I know this is a bit dirty code but I've achieved what I was looking for. It replaces the given query string or adds new one if it doesn't exist yet.
function updateUrlParameter(url, param, value) {
var index = url.indexOf("?");
if (index > 0) {
var u = url.substring(index + 1).split("&");
var params = new Array(u.length);
var p;
var found = false;
for (var i = 0; i < u.length; i++) {
params[i] = u[i].split("=");
if (params[i][0] === param) {
params[i][1] = value;
found = true;
}
}
if (!found) {
params.push(new Array(2));
params[params.length - 1][0] = param;
params[params.length - 1][1] = value;
}
var res = url.substring(0, index + 1) + params[0][0] + "=" + params[0][1];
for (var i = 1; i < params.length; i++) {
res += "&" + params[i][0] + "=" + params[i][1];
}
return res;
} else {
return url + "?" + param + "=" + value;
}
}
It will work when given regular URL addresses like:
updateUrlParameter('https://www.example.com/some.aspx?mid=1&id=2','id','5');
updateUrlParameter('https://www.example.com/?mid=1&id=2','id','5');
updateUrlParameter('https://www.example.com/some.aspx','id','5');
Please note It will NOT work only if any of the query string parameter name or value contains "=" and/or "&" chars. It will work just fine behind that.

*Java script code to find a specific query string and replace its value *
('input.letter').click(function () {
//0- prepare values
var qsTargeted = 'letter=' + this.value; //"letter=A";
var windowUrl = '';
var qskey = qsTargeted.split('=')[0];
var qsvalue = qsTargeted.split('=')[1];
//1- get row url
var originalURL = window.location.href;
//2- get query string part, and url
if (originalURL.split('?').length > 1) //qs is exists
{
windowUrl = originalURL.split('?')[0];
var qs = originalURL.split('?')[1];
//3- get list of query strings
var qsArray = qs.split('&');
var flag = false;
//4- try to find query string key
for (var i = 0; i < qsArray.length; i++) {
if (qsArray[i].split('=').length > 0) {
if (qskey == qsArray[i].split('=')[0]) {
//exists key
qsArray[i] = qskey + '=' + qsvalue;
flag = true;
break;
}
}
}
if (!flag)// //5- if exists modify,else add
{
qsArray.push(qsTargeted);
}
var finalQs = qsArray.join('&');
//6- prepare final url
window.location = windowUrl + '?' + finalQs;
}
else {
//6- prepare final url
//add query string
window.location = originalURL + '?' + qsTargeted;
}
})
});

Related

How to replace second specific character in url using jquery

I have the following url to work with:
...login?returnUrl=%2F%2Fprint?newdata=%test1234
I need to replace the second(last) ' ? ' by an ampersand
Please help..
You could;
url = url.replace(/\?([^\?]*)$/g, '&$1')
var url = 'your url';
//GET INDEX OF FIRST "?" CHARACTER
var index = url.indexOf("?");
//FIRST PART OF URL (BEFORE AND INCLUDING THE FIRST "?" CHARACTER)
var first_part = url.substring(0,(index+1));
//SECOND PART OF STRING (AFTER AND EXCLUDING THE FIRST "?" CHARACTER)
var second_part = url.substring((index+1), url.length);
//SECOND PART REPLACE "?" WITH "&"
var second_part_replace = second_part.replace("?","&");
//YOUR FINAL URL
var new_string = first_part+""+second_part_replace;
var count = 0;
str.replace(/\?/g, function () { return count++ == 0 ? '?' : '&'; });
var parts = url.split('?');
url = parts.slice(0, parts.length - 2).join('?') +'&'+parts[parts.length - 1];
Using slice, split and join you can achieve that. Or using some regular expressions.
Try this (targets the second one) :
var url = 'login?returnUrl=%2F%2Fprint?newdata=%test1234';
var index = url.indexOf('?', url.indexOf('?') + 1);
if (index !== -1) url = url.slice(0, index) + '&' + url.slice(index + 1);
Or this (targets the last one) :
var url = 'login?returnUrl=%2F%2Fprint?newdata=%test1234';
url = url.replace(/\?(?=[^\?]*$)/, '&');

How to get parameter value inside a string?

Here's a thing i've been trying to resolve...
We've got some data from an ajax call and the result data is between other stuff a huge string with key:value data. For example:
"2R=OK|2M=2 row(s) found|V1=1,2|"
Is it posible for js to do something like:
var value = someFunction(str, param);
so if i search for "V1" parameter it will return "1,2"
I got this running on Sql server no sweat, but i'm struggling with js to parse the string.
So far i'm able to do this by a VERY rudimentary for loop like this:
var str = "2R=OK|2M=2 row(s) found|V1=1,2|";
var param = "V1";
var arr = str.split("|");
var i = 0;
var value = "";
for(i = 0; i<arr.length; ++i){
if( arr[i].indexOf(param)>-1 ){
value = arr[i].split("=")[1];
}
}
console.log(value);
if i put that into a function it works, but i wonder if there's a more efficient way to do it, maybe some regex? but i suck at it. Hopefully somebody may shine a light on this for me?
Thanks!
This seems to work for your specific use-case:
function getValueByKey(haystack, needle) {
if (!haystack || !needle) {
return false;
}
else {
var re = new RegExp(needle + '=(.+)');
return haystack.match(re)[1];
}
}
var str = "2R=OK|2M=2 row(s) found|V1=1,2|",
test = getValueByKey(str, 'V1');
console.log(test);
JS Fiddle demo.
And, to include the separator in your search (in order to prevent somethingElseV1 matching for V1):
function getValueByKey(haystack, needle, separator) {
if (!haystack || !needle) {
return false;
}
else {
var re = new RegExp('\\' + separator + needle + '=(.+)\\' + separator);
return haystack.match(re)[1];
}
}
var str = "2R=OK|2M=2 row(s) found|V1=1,2|",
test = getValueByKey(str, 'V1', '|');
console.log(test);
JS Fiddle demo.
Note that this approach does require the use of the new RegExp() constructor (rather than creating a regex-literal using /.../) in order to pass variables into the regular expression.
Similarly, because we're using a string to create the regular expression within the constructor, we need to double-escape characters that require escaping (escaping first within the string and then escaping within in the created RegExp).
References:
RegExp.
String.match().
This should work for you and it's delimiters are configurable (if you wish to parse a similar string with different delimiters, you can just pass in the delimiters as arguments):
var parseKeyValue = (function(){
return function(str, search, keyDelim, valueDelim){
keyDelim = quote(keyDelim || '|');
valueDelim = quote(valueDelim || '=');
var regexp = new RegExp('(?:^|' + keyDelim + ')' + quote(search) + valueDelim + '(.*?)(?:' + keyDelim + '|$)');
var result = regexp.exec(str);
if(result && result.length > 1)
return result[1];
};
function quote(str){
return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}
})();
Quote function borrowed form this answer
Usage examples:
var str = "2R=OK|2M=2 row(s) found|V1=1,2|";
var param = "V1";
parseKeyValue(str, param); // "1,2"
var str = "2R=OK&2M=2 row(s) found&V1=1,2";
var param = "2R";
parseKeyValue(str, param, '&'); // "OK"
var str =
"2R=>OK\n\
2M->2 row(s) found\n\
V1->1,2";
var param = "2M";
parseKeyValue(str, param, '\n', '->'); // "2 row(s) found"
Here is another approach:
HTML:
<div id="2R"></div>
<div id="2M"></div>
<div id="V1"></div>
Javascript:
function createDictionary(input) {
var splittedInput = input.split(/[=|]/),
kvpCount = Math.floor(splittedInput.length / 2),
i, key, value,
dictionary = {};
for (i = 0; i < kvpCount; i += 1) {
key = splittedInput[i * 2];
value = splittedInput[i * 2 + 1];
dictionary[key] = value;
}
return dictionary;
}
var input = "2R=OK|2M=2 row(s) found|V1=1,2|",
dictionary = createDictionary(input),
div2R = document.getElementById("2R"),
div2M = document.getElementById("2M"),
divV1 = document.getElementById("V1");
div2R.innerHTML = dictionary["2R"];
div2M.innerHTML = dictionary["2M"];
divV1.innerHTML = dictionary["V1"];
Result:
OK
2 row(s) found
1,2

Javascript Reg Expression to replace Get Parameter in the URL

Using a regular expression, I want to write a function that will take a URL and a parameter name: ReplaceParamValueinURL (url, param, value).
If the parameter exists, it will replace the value in the URL.
If the parameter doesn't exist, it will add it to the URL along with the value.
If the parameter exists with no value, it will add the value to the parameter.
Is there an elegant way of doing all three in regex find and replace?
ReplaceParamValueinURL ("http://google.com?a=1&b=2&c=3, a , 4)
returns http://google.com?a=4&b=2&c=3
ReplaceParamValueinURL ("http://google.com?a=1&b=2&c=3, a , 4)
returns http://google.com?a=4&b=2&c=3
ReplaceParamValueinURL ("http://google.com?a=1&b=2&c=3, c , 4)
returns http://google.com?a=1&b=2&c=4
ReplaceParamValueinURL ("http://google.com?a=1&b=2&c=3, d , 5)
returns http://google.com?a=1&b=2&c=3&d=5
ReplaceParamValueinURL ("http://google.com?aaa=0&a=1&b=2&c=3, a , 6)
returns http://google.com?aaa=0&a=6&b=2&c=3
ReplaceParamValueinURL ("http://google.com?a=1&b&c=3, b , 2)
returns http://google.com?a=1&b=2&c=3
I am hoping to do this with Reg ex instead of split. I really appreciate it if you can explain your answer if the regex is too complex. Is there a jQuery function that already does this?
I guess it's a very common case but can have many corner cases.
ReplaceParamValueinURL ("http://google.com?a=1&b&c=3#test, a , 2)
returns http://google.com?a=2&b&c=3#test
No you can't do it with a single regexp, but the function is pretty simple, i've tested it with all your examples so it should work:
function ReplaceParamValueinURL (url, name, val) {
//Try to replace the parameter if it's present in the url
var count = 0;
url = url.replace(new RegExp("([\\?&]" + name + "=)[^&]+"), function (a, match) {
count = 1;
return match + val;
});
//If The parameter is not present in the url append it
if (!count) {
url += (url.indexOf("?") >=0 ? "&" : "?") + name + "=" + val;
}
return url;
}
try this,
function ReplaceParamValueinURL(url , replceparam , replaceValue)
{
regExpression = "(\\?|&)"+replceparam+"(=).(&|)";
var regExpS = new RegExp(regExpression, "gm");
var getmatch = url.match(regExpS);
var regExpSEq = new RegExp("=", "g");
var getEqalpostion = regExpSEq.exec(getmatch);
var newValue;
if(getmatch[0].charAt(getmatch[0].length - 1) != "&")
{
var subSrtingToReplace = getmatch[0].substring((getEqalpostion.index+ 1),getmatch[0].length );
newValue = getmatch[0].replace(subSrtingToReplace , replaceValue);
}
else
{
var subSrtingToReplace = getmatch[0].substring((getEqalpostion.index+ 1) , getmatch[0].length - 1 );
newValue = getmatch[0].replace(subSrtingToReplace , replaceValue);
}
return returnString = url.replace(regExpS , newValue);
}

Remove all occurrences except last?

I want to remove all occurrences of substring = . in a string except the last one.
E.G:
1.2.3.4
should become:
123.4
You can use regex with positive look ahead,
"1.2.3.4".replace(/[.](?=.*[.])/g, "");
2-liner:
function removeAllButLast(string, token) {
/* Requires STRING not contain TOKEN */
var parts = string.split(token);
return parts.slice(0,-1).join('') + token + parts.slice(-1)
}
Alternative version without the requirement on the string argument:
function removeAllButLast(string, token) {
var parts = string.split(token);
if (parts[1]===undefined)
return string;
else
return parts.slice(0,-1).join('') + token + parts.slice(-1)
}
Demo:
> removeAllButLast('a.b.c.d', '.')
"abc.d"
The following one-liner is a regular expression that takes advantage of the fact that the * character is greedy, and that replace will leave the string alone if no match is found. It works by matching [longest string including dots][dot] and leaving [rest of string], and if a match is found it strips all '.'s from it:
'a.b.c.d'.replace(/(.*)\./, x => x.replace(/\./g,'')+'.')
(If your string contains newlines, you will have to use [.\n] rather than naked .s)
You can do something like this:
var str = '1.2.3.4';
var last = str.lastIndexOf('.');
var butLast = str.substring(0, last).replace(/\./g, '');
var res = butLast + str.substring(last);
Live example:
http://jsfiddle.net/qwjaW/
You could take a positive lookahead (for keeping the last dot, if any) and replace the first coming dots.
var string = '1.2.3.4';
console.log(string.replace(/\.(?=.*\.)/g, ''));
A replaceAllButLast function is more useful than a removeAllButLast function. When you want to remove just replace with an empty string:
function replaceAllButLast(str, pOld, pNew) {
var parts = str.split(pOld)
if (parts.length === 1) return str
return parts.slice(0, -1).join(pNew) + pOld + parts.slice(-1)
}
var test = 'hello there hello there hello there'
test = replaceAllButLast(test, ' there', '')
console.log(test) // hello hello hello there
Found a much better way of doing this. Here is replaceAllButLast and appendAllButLast as they should be done. The latter does a replace whilst preserving the original match. To remove, just replace with an empty string.
var str = "hello there hello there hello there"
function replaceAllButLast(str, regex, replace) {
var reg = new RegExp(regex, 'g')
return str.replace(reg, function(match, offset, str) {
var follow = str.slice(offset);
var isLast = follow.match(reg).length == 1;
return (isLast) ? match : replace
})
}
function appendAllButLast(str, regex, append) {
var reg = new RegExp(regex, 'g')
return str.replace(reg, function(match, offset, str) {
var follow = str.slice(offset);
var isLast = follow.match(reg).length == 1;
return (isLast) ? match : match + append
})
}
var replaced = replaceAllButLast(str, / there/, ' world')
console.log(replaced)
var appended = appendAllButLast(str, / there/, ' fred')
console.log(appended)
Thanks to #leaf for these masterpieces which he gave here.
You could reverse the string, remove all occurrences of substring except the first, and reverse it again to get what you want.
function formatString() {
var arr = ('1.2.3.4').split('.');
var arrLen = arr.length-1;
var outputString = '.' + arr[arrLen];
for (var i=arr.length-2; i >= 0; i--) {
outputString = arr[i]+outputString;
}
alert(outputString);
}
See it in action here: http://jsbin.com/izebay
var s='1.2.3.4';
s=s.split('.');
s.splice(s.length-1,0,'.');
s.join('');
123.4

Exempting characters in an escaped string

I have a little function that makes URL arguments out of an object:
function MkArgs(o) {
var ret = '?';
for (var i in o) {
ret += i + '=' + escape(o[i]) + '&';
}
return ret.substr(0, ret.length - 1);
}
which I then can call like this:
MkArgs({
protocol: 'wsfederation',
realm: 'https://www.x.com/',
fedRes: 'Home/FederationResult',
context: '~/Home/FAQ',
version: '1.0',
callback: '?'
});
to produce the following:
?protocol=wsfederation&realm=https%3A//www.x.com/&fedRes=Home/FederationResult&context=%7E/Home/FAQ&version=1.0&callback=%3F
everything is fine except that I don't want the last argument escaped i.e. I want:
callback=?
instead of
callback=%3F
is there any way I can indicate that within the string? I tried '\?' but that doesn't do it and haven't found any references as to how to protect a piece of string from escaping...
e
The MkArgs function is your own; change it to include an escape mechanism. I would advise against using backslash, though. If this is just your own code, perhaps it would be enough to put in a hackish special case.
That's a pretty special case. Maybe you should change your function:
function MkArgs(o, isJSONP) {
var ret = '?';
for (var i in o) {
var val = o[i];
val = escape(val);
ret += i + '=' + val + '&';
}
return ret.substr(0, ret.length - 1) + isJSONP ? '&callback=?':'';
}
and call it:
MkArgs({
protocol: 'wsfederation',
realm: 'https://www.x.com/',
fedRes: 'Home/FederationResult',
context: '~/Home/FAQ',
version: '1.0'
}, true);
The escape or encodeURIComponent functions don't have any way of "skipping" certain characters. So, all you can do is to either avoid calling the encode function when you don't want to or replace the chars you don't want encoded, call encode and then put the original chars back again.
If you want to skip escaping the whole value for a particular key, you can just check for the particular keys that you don't want to escape and handle appropriately like this:
function MkArgs(o) {
var ret = '?';
for (var i in o) {
var val = o[i];
if (i != "callback") {
val = encodeURIComponent(val);
}
ret += i + '=' + val + '&';
}
return ret.substr(0, ret.length - 1);
}
If you want to skip just certain characters, then you can replace them with some unique sequence, escape and then put them back:
function MkArgs(o) {
var ret = '?';
for (var i in o) {
var val = o[i];
if (i == "callback") {
val = val.replace(/\?/, "--xx--"); // replace with unique sequence
val = encodeURIComponent(val);
val = val.replace(/--xx--/, "?"); // put orig characters back
} else {
val = encodeURIComponent(val);
}
ret += i + '=' + val + '&';
}
return ret.substr(0, ret.length - 1);
}
FYI, note I've switched to using encodeURIComponent() which is recommended over the deprecated escape() because escape() doesn't work for non-ascii characters.
thanks everyone for the replies. what I ended up doing was:
function MkArgs(o) {
var ret = '?';
for (var i in o) {
ret += i;
if (o[i]) ret += '=' + escape(o[i]);
ret += '&';
}
return ret.substr(0, ret.length - 1);
}
then calling it like:
MkArgs({
protocol: 'wsfederation',
realm: 'https://www.x.com/',
fedRes: 'Home/FederationResult',
context: '~/Home/FAQ',
version: '1.0',
'callback=?': null
});
that way I don't rely on the values but the keys to make the distinction. not really pretty but it's the best I could think of
function MkArgs(o) {
var ret = '?';
var lastEl = '';
for (var i in o) {
ret += i + '=' + escape(o[i]) + '&';
lastEl = o[i];
}
return ret.substr(0, ret.length - 1 - lastEl.length) + lastEl;
}
this works for the last element in the object.
EDIT: It seems that in a classic for in loop, javascript does not have a precise order in which it loops over the object props, so the above solution is not guaranteed to work.
In this case you have 2 solutions :
If you know which property you want to "protect" from escaping, you should check for that prop in the loop and specifically not escape it :
for (var i in o) {
if(i=="myProp")
// unescape
else
// escape
}
If you do not now the property, but you want only the last one added into the query, you can do something like this (after building the query) :
var q = MkArgs(o);
var parts = q.split('=');
var toUnescape = parts[parts.length-1];
q = q.substring(0,q.length - toUnescape.length) + unescape(toUnescape);

Categories

Resources