Regex for removing part of URL param - javascript

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);

Related

How can I replace all duplicated paths of a url with a JS Regex

For the following URL:
https://www.google.es/test/test/hello/world
I want to replace all the occurrences of "/test/", and its important that it "test" starts with and ends with a "/".
I tried with:
let url = "https://www.google.es/test/test/hello/world"
url.replace(/\/test\//g, "/");
But it returns:
'https://www.google.es/test/hello/world'
It doesn't replace the second "/test/"
Any clues on how I could do this with a regex?
I basically want to replace the content that lives inside the dashes, but not the dashes themselves.
Something like this would work:
/(\/[^\/]+)(?:\1)+\//g
( - open capture group #1
\/ - find a literal slash
[^\/]+ - capture at least one non-slash char
) - close capture group #1
(?:\1)+ - repeat capture group #1 one or more times
\/ - ensure a closing slash
/g - global modifier
https://regex101.com/r/NgJA3X/1
var regex = /(\/[^\/]+)(?:\1)+\//g;
var str = `https://www.google.es/test/test/hello/world
https://www.google.es/test/test/test/test/hello/world
https://www.google.es/test/test/hello/test/hello/hello/world
https://www.google.es/test/hello/world/world
https://www.google.es/test/hello/helloworld/world`;
var subst = ``;
// The substituted value will be contained in the result variable
var result = str.replace(regex, subst);
console.log(result);
You can do this with a regular expression, but it sounds like your intent is to replace only individual parts of the pathname component of a URL.
A URL has other components (such as the fragment identifier) which could contain the pattern that you describe, and handling that distinction with a regular expression is more challenging.
The URL class is designed to help solve problems just like this, and you can replace just the path parts using a functional technique like this:
function replacePathParts (url, targetStr, replaceStr = '') {
url = new URL(url);
const updatedPathname = url.pathname
.split('/')
.map(str => str === targetStr ? replaceStr : str)
.filter(Boolean)
.join('/');
url.pathname = updatedPathname;
return url.href;
}
const inputUrl = 'https://www.google.es/test/test/hello/world';
const result1 = replacePathParts(inputUrl, 'test');
console.log(result1); // "https://www.google.es/hello/world"
const result2 = replacePathParts(inputUrl, 'test', 'message');
console.log(result2); // "https://www.google.es/message/message/hello/world"
Based on conversation in comment, you can use this solution:
let url = "https://www.google.es/test/test/hello/world"
console.log( url.replace(/(?:\/test)+(?=\/)/g, "/WORKS") );
//=> https://www.google.es/WORKS/hello/world
RegEx Breakdown:
(?:\/test)+: Match 1+ repeats of text /test
(?=\/): Lookahead to assert that we have a / ahead

Javascript : Get value of first and second slash

How do i get first and second slash of a URL in javascript?
URL : http://localhost:8089/submodule/module/home.html
Now i want the value /submodule/module
Below is the code i have been trying
window.location.pathname.substring(0, window.location.pathname.indexOf("/",2))
This got me only /submodule
window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/",window.location.pathname.lastIndexOf("/")-1))
Also this didnt work. Can anyone please guide where i am going wrong.
This should work, it take everything exept the last element of pathname:
let result = window.location.pathname.split('/').slice(0,-1).join('/') + '/'
Only the 1st and 2de item:
let result = window.location.pathname.split('/').slice(0,2).join('/') + '/'
Handle path without file :
// ex: /foo/bar/path.html > foo/bar/
// ex: /foo/bar/ > foo/bar/
let result = (window.location.pathname[window.location.pathname.length -1] !== '/') ? window.location.pathname.split('/').slice(0,-1).join('/') + '/' : window.location.pathname
You can use the split() function, for example like this:
var url = 'http://localhost:8089/submodule/module/home.html';
var parts = url.split('/');
console.log('/' + parts[3] + '/' + parts[4]);
The output will be:
/submodule/module
Try this:
var pathParts = window.location.pathname.split('/');
var result = `${pathParts[1]}/${pathParths[2]}`;
Using a regular expression:
var url = 'http://localhost:8089/submodule/module/home.html'; //or window.location.pathname
var re = /\/\/.+(\/.+\/.+)\/.+/
re.exec(url)[1];
This expression basically says the url is in the format
//[anything](/submodule/module)/[anything]
and to get everything in parentheses.
Functional style
/\/[^/]*\/[^/]*/.exec(window.location.pathname)[0]
You could use a regular expression:
var url = ...
var part = url.match(/https?:\/\/.*?(\/.*?\/.*?)\/.*/)[1]
Explanation:
http Match the group 'http'
s? Match 1 or 0 's'
: Match a semicolon
\/\/ Match '//'
.*? Match anything (non-greedy)
( Start capturing block (Everything captured will be an array element)
\/*?\/.*? Something that looks like /.../...
) End capturing block
\/.* Something that looks like /...
The output of the match method will be an array with 2 elements. The first one is the whole matched string, and the second is the captured group.

Get last part of url with / at the end

I'm trying to get the last part of this url:
http://webserver/Foo/login/
the code that I wrote:
var location = window.location.href.split('/').pop();
will return an empty string 'cause after the / there is nothing.
I need to get at least the previous part, so in this case, login.
How can I do this?
The solution using String.replace()(used to replace possible / at the end of the string) and String.split() functions:
var url = 'http://webserver/Foo/login/',
last_section = url.replace(/\/+$/, '').split('/').pop();
console.log(last_section);
const getLastPartURL = url => {
const parts = url.split('/');
const length = parts.length;
return parts[length - 1] == '' ? parts[length - 2] : parts[length - 1]
}
console.log(getLastPartURL('http://webserver/Foo/login/'))
console.log(getLastPartURL('http://webserver/Foo/login'))
console.log(getLastPartURL('http://webserver/Foo/'))
console.log(getLastPartURL('http://webserver/Foo'))
This should do the trick:
location.pathname.match(/[^/]*(?=\/*$)/)[0]
Explanation:
Location.pathname is a string containing an initial '/' followed by the path of the URL.
String.prototype.match(regexp) returns an array of the matches.
[^/]* matches anything but a slash, and that zero or more times.
(?=\/*$) matches a slash zero or more times at the end of the string, while not including it.
There is always exactly one match, so we retrieve it with [0].
Example:
For all these URLs the output is login:
http://webserver/Foo/login
http://webserver/Foo/login/
http://webserver/Foo/login//

JavaScript regex to remove variable from query

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;
}

How do I extract data from this URL using javascript?

I need to build a string from the data contained in this url using javascript/jQuery:
http://www.example.com/members/admin/projects/?projectid=41
The string returned should look as follows:
/ajax/projects.php?projectid=41
Obviously if there is no query string present, the method should still return a string of the same format minus the query string. e.g.
http://www.example.com/members/admin/messages/
should return...
/ajax/messages.php
I've made numerous attempts, all met without success due to my poor grasp of regular expressions, and it feels as though the ore I rad on the subject the more I am confusing myself.
If someone could help it would be greatly appreciated.
EDIT: The 'admin' portion of the url is a users 'username' and could be anything.
Here's a function that will take your URL and return a new one according to the rules you've listed above:
function processURL(url) {
var base = "", query = "";
var matches = url.match(/([^\/\?]+)(\/$|$|\?|\/\?)/);
if (matches) {
base = matches[1];
matches = url.match(/\?[^\?]+$/);
if (matches) {
query = matches[0];
}
}
return("/ajax/" + base + ".php" + query);
}
And, a test app that shows it working on a bunch of URLs: http://jsfiddle.net/jfriend00/UbDfn/
Input URLs:
var urls = [
"http://www.example.com/members/admin/projects/?projectid=41",
"http://www.example.com/members/bob/messages/",
"http://www.example.com/members/jill/projects/",
"http://www.example.com/members/alice/projects?testid=99",
"http://www.example.com/members/admin/projects/?testid=99"
];
Output results:
/ajax/projects.php?projectid=41
/ajax/messages.php
/ajax/projects.php
/ajax/projects.php?testid=99
/ajax/projects.php?testid=99
To explain, the first regular expression looks for:
a slash
followed by one or more characters that is not a slash and not a question mark
followed by one of the four sequences
/$ a slash at the end of the string
$ end of the string
? a question mark
/? a slash followed by a question mark
The point of this regex is to get the last segment of the path that comes before either the end of the string or the query parameters and it's tolerant of whether the last trailing slash is there or not and whether there are any query parameters.
I know exactly what you are trying to do. In order to do it your way just split your string on question mark and then use last item form your array.
var data = your_url.split('?');
var newUrl = '/ajax/projects.php' + (data.length > 1 ? data[length-1] : "");
and you will have your url.
But what you can do is execute same url using your Script just add one parameter IsAjax=true and then check it in codebehind and execute your ajax logic.
e.g.
$('#somelink').onclick(function(){
$.ajax({ url: $(this).href, data { IsAjax: true } .... }
});
Using this way you will have more robust app.
I'll assume that by
http://www.example.com/members/admin/messages/
should return...
/ajax/members.php
you meant - should return...
/ajax/messages.php
If that is the case try
var query = url.split('?');
var paths = query[0].split('/');
var path = paths.pop();
if (path == '') //when there is trailing slash
path = paths.pop();
if (query.length == 1) //no query string
newurl = '/ajax/' + path + '.php';
else //query string
newurl = '/ajax/' + path + '.php?' + query[1];
I'm sure it can be made simpler and better, but that might give you a start.
var str = "http://www.example.com/members/admin/projects/?projectid=41";
var newStr = "/ajax/" + str.split("/").slice(-2).join(".php");
console.log(newStr);

Categories

Resources