I'm trying to remove a variable from a query string. This is my current approach:
var str = "http://example.com/tal.php?sec=16&name=xxxx&size=xxxx";
str = str.replace(/([&])name=.*?(&|$)/g,"");
There are two problems with this code:
Both the & at the beginning of name and at the end get removed. I'd like only one to be removed
It should also work when the variable name is at the beginning or at the end of the query string.
How can I tell the regex to delete the second & only if it has matched the first one?
I suggest using capturing groups and then using them in the callback function to re-insert the & character appropriately:
([?&])name=.*?($|&)
See demo
Here is a JavaScript snippet showing replacement process in all the 3 positions:
function removeQueryArg(str) {
var re = /([?&])name=.*?($|&)/;
return str.replace(re, function(m, grp1, grp2, offset, input) {
return grp1 === "?" ? "?" : (grp2 === "&" ? "&" : "");
});
}
document.write(removeQueryArg('http://example.com/tal.php?name=xxxx&sec=16&size=xxxx') + "<br/>" +
removeQueryArg('http://example.com/tal.php?sec=16&name=xxxx&size=xxxx') + "<br/>" +
removeQueryArg('http://example.com/tal.php?sec=16&size=xxxx&name=xxxx'));
Let me explain:
The ([?&])name=.*?($|&) regex contains 2 capturing groups ([?&]) (matching either ? or &) and ($|&) (matching end of string or &).
Inside the replace method, we can pass the contents of these groups to the callback function where we can further analyze what to do with the replacement.
function(m, grp1, grp2, offset, input) actually uses the whole match m, and grp1 and grp2 are the captured texts. offset (match index in the original string) and input (the whole input string) are not used here, but they might turn out useful some day.
In the callback, I am checking if group 1 is equal to "?". If yes, the argument is in the beginning of the query string, and we need to restore the ? in front.
If not, we need to check the contents of the 2nd group. If it is equal to &, the match is in the middle of the query string, we need to add &. If not, we are at the end, do not add anything, we remove the whole match.
See more at Specifying a function as a parameter at MDN replace method help page.
A simple way to solve this is to delete the name parameter together with the question mark or ampersand that precedes it. If the question mark gets deleted, put it back in by replacing the first ampersand with a question mark.
s = s.replace(/([?&]name=[^&]*)/, '');
if (s.indexOf('?') == -1) {
s = s.replace(/[&]/, '?');
}
Demonstration:
function print(s) {
document.write(s + '<br \>');
}
function deleteName(s) {
print(s);
s = s.replace(/([?&]name=[^&]*)/, '');
if (s.indexOf('?') == -1) {
s = s.replace(/[&]/, '?');
}
print(s);
print('');
}
deleteName('http://example.com/tal.php?name=xxxx&sec=16&size=xxxx');
deleteName('http://example.com/tal.php?sec=16&name=xxxx&size=xxxx');
deleteName('http://example.com/tal.php?sec=16&size=xxxx&name=xxxx');
body {
font-family: sans-serif;
}
Related
Unable to retrieve full string if partially matched.
Example:
src = 'The expression $ a{\color{blue}{x}}^2 + b{\color{blue}{x}} + c$ is said to be quadratic when TAtrimg001a.svg is \neq 0$'
search for "svg" > should return TAtrimg001a.svg
I am trying to search and find the string "svg". If the "svg" exists then it should return TAtrimg001a.svg not just its location or the word svg itself but the complete svg filename.
In reply to a comment...
I tried finding the match in following differenet ways, but they do really work for my requirment, example:
var res = str.match(/svg/ig);
var res = str.search("svg");
var res = str.indexOf( "svg" )
Straightforward with regex. The string .match method takes a regex and returns either:
null if there was no match.
An array otherwise, where the first element is the entire matched string, and the remaining elements are each respective capture group (if any).
So for this case, you just want the whole match, so just taking that first item should be fine. The example regex below just looks for any string of non-whitespace characters that ends with .svg. You may want to broaden or tighten that to meet your exact use case.
src = 'The expression $ a{\color{blue}{x}}^2 + b{\color{blue}{x}} + c$ is said to be quadratic when TAtrimg001a.svg is \neq 0$'
function findFileName(str, ext) {
const match = str.match(new RegExp(`\\w+\\.${ext}`));
return match && match[0]
}
console.log(findFileName(src, "svg"))
Minor Note: When passing a string to the RegExp constructor, backslashes must be doubled, since the first backslash escapes the second as part of the string.
In ES6 you can do something like const result = str.endsWith(".svg") ? str : null;, which will store in result variable full file name (if it ends with ".svg" part, in other words, has svg format), or null (if it doesn't):
function checkIsFileOfType(str, fileType) {
return str.endsWith("." + fileType) ? str : null;
}
console.log(checkIsFileOfType("TAtrimg001a.svD", "svg"));
console.log(checkIsFileOfType("TAtrimg001a.svg", "svg"));
I am trying use regex to remove a particular param in a url.
//Here are the scenarios of what I want to remove in the url
'?pIds=123,2311' => ''
'?pIds=123,2311&deal=true' => '?deals=true'
'?pIds=123' => ''
'?pIds=123&deals=true' => '?deals=true'
'&pIds=123,2311' => ''
'&pIds=123,2311&deals=true' => '&deals=true'
'&pIds=123' => ''
'&pIds=123&deals=true' => '&deals=true'
const a = '?pIds=123,2311&deals=true';
a.replace(/&?pIds=\d+,?\d+/i, '');
Is this possible to create a single regex for these scenarios? How can I conditionally have ? or & there if pIds is the first or middle param, respectively?
You can use this regex in Javascript for searching:
/[?&]pIds=[^&]*$|([?&])pIds=[^&]*&/
RegEx Breakup:
[?&]pIds=[^&]*$: Match ? or & followed by pIds=. $ ensures this is the only parameter in query string.
|: OR
([?&])pIds=[^&]*&: Match ? or & followed by pIds= followed by &. This is the case where there is one more parameter in query string.
Code:
var arr=['?pIds=123,2311',
'?pIds=123,2311&deal=true',
'?pIds=123',
'?pIds=123&deals=true',
'&pIds=123,2311',
'&pIds=123,2311&deals=true',
'&pIds=123',
'&pIds=123&deals=true'];
var re = /[?&]pIds=[^&]*$|([?&])pIds=[^&]*&/;
for (i=0; i<arr.length; i++) {
console.log(arr[i], ' => ', arr[i].replace(re, '$1'));
}
RegEx Demo
The regex to identify the block you are talking about is something like the following:
((?<=\?)|\&)pIds=\d+(,\d+)?
The first part is a "positive lookbehind" for a question mark, which will match if there is a question mark before pIds, but it will not include the question mark as part of the match. An ampersand also works, but it is included as part of the match, so it will get deleted.
I also made the treatment of the optional comma and numbers a little bit clearer. You always have one block of numbers (\d+), optionally followed by a comma and another block of numbers.
Edit: In my original post, I forgot to treat the ampersands properly. If the string begins with a question mark and there is no ampersand, you want to delete the question mark. If it starts with a question mark and ends with an ampersand, you want to delete the ampersand at the end. If it both begins and ends with an ampersand, you need to delete one of them. If it begins with an ampersand and does not end with one, you need to delete the one at the beginning. The result is slightly more complicated and looks like this:
\?pIds=\d+(,\d+)?($|[^&])|(?<=\?)pIds=\d+(,\d+)?\&|\&pIds=\d+(,\d+)
The first case takes care of no ampersand at the end (($|[^&]) corresponds to either end-of-line or no ampersand). The second case takes care of beginning with ? and ending with &. The third case takes care of the remaining two scenarios, where there is a & at the beginning.
There are loads of ways to do this. Here is a version without regex:
let url1 = 'foo.bar?pIds=123,2311&deals=true&foo=bar';
let parsedUrl;
let queryParts;
// Get the query string from the URL
parsedUrl = url1.split('?');
// Split the query string so we get each key value then filter so we dont get the pIds
queryParts = parsedUrl[1].split('&').filter(q => q.indexOf('pIds') === -1);
// set URL to the original hostname and a ? if we have a query still
url1 = (queryParts.length > 0 ? '?' : '')
// Join the query parts
url1 += queryParts.join('&')
console.log(url1);
More examples:
let url2 = 'foo.bar?pIds=123,2311';
parsedUrl = url2.split('?');
queryParts = parsedUrl[1].split('&').filter(q => q.indexOf('pIds') === -1);
url2 = parsedUrl[0] + (queryParts.length > 0 ? '?' : '')
url2 += queryParts.join('&')
console.log(url2);
let url3 = 'foo.bar?foo=bar&pIds=123,2311';
parsedUrl = url3.split('?');
queryParts = parsedUrl[1].split('&').filter(q => q.indexOf('pIds') === -1);
url3 = parsedUrl[0] + (queryParts.length > 0 ? '?' : '')
url3 += queryParts.join('&')
console.log(url3);
I'm trying to extract out a group of words from a larger string/cookie that are separated by hyphens. I would like to replace the hyphens with a space and set to a variable. Javascript or jQuery.
As an example, the larger string has a name and value like this within it:
facility=34222%7CConner-Department-Store;
(notice the leading "C")
So first, I need to match()/find facility=34222%7CConner-Department-Store; with regex. Then break it down to "Conner Department Store"
var cookie = document.cookie;
var facilityValue = cookie.match( REGEX ); ??
var test = "store=874635%7Csomethingelse;facility=34222%7CConner-Department-Store;store=874635%7Csomethingelse;";
var test2 = test.replace(/^(.*)facility=([^;]+)(.*)$/, function(matchedString, match1, match2, match3){
return decodeURIComponent(match2);
});
console.log( test2 );
console.log( test2.split('|')[1].replace(/[-]/g, ' ') );
If I understood it correctly, you want to make a phrase by getting all the words between hyphens and disallowing two successive Uppercase letters in a word, so I'd prefer using Regex in that case.
This is a Regex solution, that works dynamically with any cookies in the same format and extract the wanted sentence from it:
var matches = str.match(/([A-Z][a-z]+)-?/g);
console.log(matches.map(function(m) {
return m.replace('-', '');
}).join(" "));
Demo:
var str = "facility=34222%7CConner-Department-Store;";
var matches = str.match(/([A-Z][a-z]+)-?/g);
console.log(matches.map(function(m) {
return m.replace('-', '');
}).join(" "));
Explanation:
Use this Regex (/([A-Z][a-z]+)-?/g to match the words between -.
Replace any - occurence in the matched words.
Then just join these matches array with white space.
Ok,
first, you should decode this string as follows:
var str = "facility=34222%7CConner-Department-Store;"
var decoded = decodeURIComponent(str);
// decoded = "facility=34222|Conner-Department-Store;"
Then you have multiple possibilities to split up this string.
The easiest way is to use substring()
var solution1 = decoded.substring(decoded.indexOf('|') + 1, decoded.length)
// solution1 = "Conner-Department-Store;"
solution1 = solution1.replace('-', ' ');
// solution1 = "Conner Department Store;"
As you can see, substring(arg1, arg2) returns the string, starting at index arg1 and ending at index arg2. See Full Documentation here
If you want to cut the last ; just set decoded.length - 1 as arg2 in the snippet above.
decoded.substring(decoded.indexOf('|') + 1, decoded.length - 1)
//returns "Conner-Department-Store"
or all above in just one line:
decoded.substring(decoded.indexOf('|') + 1, decoded.length - 1).replace('-', ' ')
If you want still to use a regular Expression to retrieve (perhaps more) data out of the string, you could use something similar to this snippet:
var solution2 = "";
var regEx= /([A-Za-z]*)=([0-9]*)\|(\S[^:\/?#\[\]\#\;\,']*)/;
if (regEx.test(decoded)) {
solution2 = decoded.match(regEx);
/* returns
[0:"facility=34222|Conner-Department-Store",
1:"facility",
2:"34222",
3:"Conner-Department-Store",
index:0,
input:"facility=34222|Conner-Department-Store;"
length:4] */
solution2 = solution2[3].replace('-', ' ');
// "Conner Department Store"
}
I have applied some rules for the regex to work, feel free to modify them according your needs.
facility can be any Word built with alphabetical characters lower and uppercase (no other chars) at any length
= needs to be the char =
34222 can be any number but no other characters
| needs to be the char |
Conner-Department-Store can be any characters except one of the following (reserved delimiters): :/?#[]#;,'
Hope this helps :)
edit: to find only the part
facility=34222%7CConner-Department-Store; just modify the regex to
match facility= instead of ([A-z]*)=:
/(facility)=([0-9]*)\|(\S[^:\/?#\[\]\#\;\,']*)/
You can use cookies.js, a mini framework from MDN (Mozilla Developer Network).
Simply include the cookies.js file in your application, and write:
docCookies.getItem("Connor Department Store");
I am trying to replace something like '?order=height' and I know it can be easily done like this:
data = 'height'
x = '?order=' + data
x.replace('?order=' + data, '')
But the problem is that question mark can sometimes be ampersand.. What I really wish to do is make blank whether the first character is ampersand or question mark so basically whether
?order=height
&order=height
can be made a blank string
x.replace(/[&?]order=height/, '')
If data is string variable
x.replace(/[&?]order=([^&=]+)/, '')
Use regex for that .replace(/[?&]order=height/, '')
[?&] means any character from this list.
/ is start and end delimiter.
Please note that pattern is not enclosed as string with ' or ".
This is how you may do it. Create a RegExp object with
"[&?]order=" + match
and replace with "" using String.prototype.replace
function replace(match, str) {
regex = new RegExp("[&?]order=" + match,"g")
return str.replace(regex, "")
}
console.log(replace("height", "Yo &order=height Yo"))
console.log(replace("weight", "Yo ?order=weight Yo"))
console.log(replace("age", "Yo ?order=age Yo"))
<font color="green">+4,13</font>%
I know that I shouldn't use regular expressions for that, but that's a single case where my only html is that so...
how can I get "4,13" from the string above?
EDIT
Context:
I am sorting a table via jQuery TableSorter. A column contains that html-formatted data and I can't change it. The custom parser I'm writing has a format function, which I currently use for managing currency, percentages and so on...
Now, I want to check, with a regex, if the string that comes to me is a string.
format: function(s) {
console.log(s);
var stripped = s.replace("<font>","")
.replace("</font>", "");
return jQuery.tablesorter.formatFloat(stripped);
}
This should work for your specific example -
var tagtext = '<font color="green">+0.00</font>%';
var keepplusorminus = false;
var myregexp = keepplusorminus ? /[-\+,\.0-9]+/ : /[,\.0-9]+/;
var match = myregexp.exec(tagtext);
if (match != null) {
result = match[0];
} else {
result = "";
}
alert(result);
Working demo - http://jsfiddle.net/ipr101/LHBp7/
Edit
If you just want to match numbers
[+-]?\d+(?:[,.]\d+)?
See it here on Regexr
Matches for an optional + or - then at least one digit, then an optional fraction with a . or a , as fraction delimiter.
/Edit
Try something like this
<font color="green">([^<]+)
You will then find the value "+4,13" in the capturing group 1.
See it here on Regexr
If you want to exclude the + than add it (maybe optional) before the capturing group
<font color="green">\+?([^<]+)