I have response url in window.location.href and I need the value for error, error_description and state from it
http://localhost:4200/#error=access_denied&error_description=AADB2C90118%3a+The+user+has+forgotten+their+password.%0d%0aCorrelation+ID%3a+a7916eb9-4404-4cc5-b5a3-ee3211237566%0d%0aTimestamp%3a+2018-02-05+09%3a19%3a07Z%0d%0alogin_hint%3a+kzahid%40opm.co.uk%0d%0a&state=da2d6e3c-cb6f-1d3b-909b-c6412325b3
I am using following code but getting null value
var messageType = new RegExp('[\?&]' + "error" + '=([^&#]*)').exec(window.location.href);
I need find this string from url "The user has forgotten their password"
Your problem here is that your URL parameters are preceded by a #, not a ?.
So, simply replace it and access the parameters using URLSearchParams#get():
var prevUrl = "http://localhost:4200/#error=access_denied&error_description=AADB2C90118%3a+The+user+has+forgotten+their+password.%0d%0aCorrelation+ID%3a+a7916eb9-4404-4cc5-b5a3-ee3211237566%0d%0aTimestamp%3a+2018-02-05+09%3a19%3a07Z%0d%0alogin_hint%3a+kzahid%40opm.co.uk%0d%0a&state=da2d6e3c-cb6f-1d3b-909b-c6412325b3";
var url = new URL(prevUrl.replace(/#/,'?'));
console.log(url.searchParams.get("error"));
console.log(url.searchParams.get("error_description"));
In a (modern) browser you can use the new URL() to parse your url and extract query parameters easily.
var location_url="http://localhost:4200/#error=access_denied&error_description=AADB2C90118%3a+The+user+has+forgotten+their+password.%0d%0aCorrelation+ID%3a+a7916eb9-4404-4cc5-b5a3-ee3211237566%0d%0aTimestamp%3a+2018-02-05+09%3a19%3a07Z%0d%0alogin_hint%3a+kzahid%40opm.co.uk%0d%0a&state=da2d6e3c-cb6f-1d3b-909b-c6412325b3";
//To make it work you have to replace "/#" with '?' so that new URL() constructor parses the url properly.
location_url=location_url.replace('\/#','?');
var url = new URL(location_url);
var error = url.searchParams.get("error");
console.log(error);
You could split by & and then split items by =.
// what you would do:
//const hash = location.hash;
// for demo purposes:
const hash = '#error=access_denied&error_description=AADB2C90118%3a+The+user+has+forgotten+their+password.%0d%0aCorrelation+ID%3a+a7916eb9-4404-4cc5-b5a3-ee3211237566%0d%0aTimestamp%3a+2018-02-05+09%3a19%3a07Z%0d%0alogin_hint%3a+kzahid%40opm.co.uk%0d%0a&state=da2d6e3c-cb6f-1d3b-909b-c6412325b3';
const hashParams = hash.substr(1).split('&')
.reduce((obj, groupStr) =>
Object.assign(obj, {
[groupStr.split('=')[0]]: groupStr.split('=')[1]
}), {});
console.log(hashParams);
console.log(hashParams.error_description);
use reg like this:
let url='http://localhost:4200/#error=access_denied&error_description=AADB2C90118%3a+The+user+has+forgotten+their+password.%0d%0aCorrelation+ID%3a+a7916eb9-4404-4cc5-b5a3-ee3211237566%0d%0aTimestamp%3a+2018-02-05+09%3a19%3a07Z%0d%0alogin_hint%3a+kzahid%40opm.co.uk%0d%0a&state=da2d6e3c-cb6f-1d3b-909b-c6412325b3';
let result=url.match(/error_description=([\s\S]*?)\./)[1].split('+');
result.shift();
console.log(result.join(' '));
If you still want to use a RegExp even though might be an overkill having the new options from the previous answers, you can use a RegExp like this:
const regex = /(error|error_description)=(.+?)&/g;
const str = `http://localhost:4200/#error=access_denied&error_description=AADB2C90118%3a+The+user+has+forgotten+their+password.%0d%0aCorrelation+ID%3a+a7916eb9-4404-4cc5-b5a3-ee3211237566%0d%0aTimestamp%3a+2018-02-05+09%3a19%3a07Z%0d%0alogin_hint%3a+kzahid%40opm.co.uk%0d%0a&state=da2d6e3c-cb6f-1d3b-909b-c6412325b3`;
let matches;
while ((matches = regex.exec(str)) !== null) {
if (matches.index === regex.lastIndex) {
regex.lastIndex++;
}
matches.forEach((match, groupIndex) => {
if (groupIndex === 1 )
console.log(`Param: ${match}`);
if (groupIndex === 2 )
console.log(`Value: ${match}`);
});
}
/(error|error_description)=(.+?)&/g
Here you have 2 capture groups inside the full match, so you can get separatedly the parameter name and its value.
(error|error_description) -> will match either error or error_description
(.+?) -> will match from 1 to any characters until it finds the next character match, stated in this case by &, as few times as possible and expanding as needed
The g (global modifier) will allow to return all the matches found.
Related
I want to test the URL http://example.com in a browser window for an empty search string, i.e http://example.com/search/?s=, but not match anything like /search/?s=withsearchterms that has any search terms after the /search/?s=, and then use an if statement and .addClass to display a div that warns that no search terms were entered.
I'm trying to use Javascript and g.test like below; the RegEx pattern is valid, according to several RegEx testers. But no luck:
var href = window.location.href;
var contains = /[\/?s=]+/g.test(href);
if (contains) {
$("#no-search-terms").addClass("display-block");
}
Is my RegEx wrong? Is my use of test wrong?
Edit 11/29/2020
This work, thanks to Heo:
var search = window.location.href;
var regex = /(?<=\/\?s=).*$/
var result=regex.exec( search )
if (result && result[0]=='') {
alert("The search terms are empty.");
} else {
alert("The search terms are not empty or no matched.");
}
But miknik's answer is much simpler with no need for regex. Works on Chrome 87, Firefox 83 and Safari 14:
const queries = new URLSearchParams(window.location.search)
if (queries.has("s") && queries.get("s").length == 0){
alert("The search terms are empty.");
}
You can test if end of string contains /?s=:
var url1 = 'https://example.com/?s=';
var url2 = 'https://example.com/?s=withsearchterms';
var regex = /\/\?s=$/;
console.log(url1 + ' ==> ' + regex.test(url1));
console.log(url2 + ' ==> ' + regex.test(url2));
Output:
https://example.com/?s= ==> true
https://example.com/?s=withsearchterms ==> false
Explanation:
\/\?s= - expect /?s=
$ - trailing $ anchors the regex at the end, e.g. preceding text must occur at the end
thus, the test returns true if the url has no search term (you can reverse your if test)
No need for regex here, something like this should work fine in modern browsers:
const queries = new URLSearchParams(window.location.search)
if (queries.has("s") && queries.get("s").length == 0){
// do stuff
}
Another alternative that (mostly) avoids regular expressions:
function isEmptySearch(urlString) {
const url = new URL(urlString);
const urlParams = url.search.replace(/^\?/, '').split('&').reduce( (acc, cur) => {
const param = cur.split('=');
acc[param[0]] = param[1];
return acc;
}, {});
return !urlParams.s;
}
const testUrls = [
"http://example.com/search/",
"http://example.com/search/?s=",
"http://example.com/search/?s=&foo=bar&baz",
"http://example.com/search/?s=hello&foo=bar&baz"
];
testUrls.forEach( url => console.log(`${url}: empty search = ${isEmptySearch(url)}`) );
I think I prefer the regex option presented earlier by Peter Thoeny as it's less verbose, but this version might be of interest.
If You want to use REGEX, you could use exec() instead of test() because the test function isn't good at the case.
Try this:
//URL-input
var href1 = 'http://example.com/?s='
var href2 = 'http://example.com/?s=xx'
var href3 = 'http://example.com/'
function alertsSearchString( href ){
var regex = /(?<=\/\?s=).*$/
var Container= regex.exec( href )
if ( Container!=null && Container[0]=='' )
alert( 'The search string is an empty string!' )
else if (Container!=null)
alert( 'The search string: ' + Container[0] )
else
alert( "The Container is "
+ Container
+", because input URL isn't matched the \nREGEX : "
+ regex.toString() )
}
//alerts-output
alertsSearchString( href1 )
alertsSearchString( href2 )
alertsSearchString( href3 )
Output:
First Alert : The search string is an empty string!
SecondAlert : The search string: xx
Third Alert : The Container is null because input URL isn't matched the
REGEX : /(?<=\/\?s=).*$/
Detail:
Regex expression: (?<=\/\?s=).*$
(?<=\/\?s=) use lookbehind to check and skip /?s=.
.* match zero to more characters after /?s=.
$ preceding text must occur at the end.
See regex-demo
The source below is an edited from your example Edit 11/22/2020 using exec()
var search = 'http://example.com/search/?s='
var regex = /(?<=\/\?s=).*$/
var result=regex.exec( search )
if (result && result[0]=='') {
alert("The search terms are empty.");
} else {
alert("The search terms are not empty or no matched.");
}
Forget regex, nodejs URL is your friend. https://nodejs.org/dist/latest-v14.x/docs/api/url.html#url_new_url_input_base
for legacy nodejs versions you can use url.parse and querystring.parse
const { URL } = require('url');
const url1 = new URL('https://example.com/?s=');
const url2 = new URL('https://example.com/?s=withsearchterms');
function hasEmptyQuery(u) {
return [...u.searchParams]
.some(([key, value]) => value.length === 0);
}
console.log(hasEmptyQuery(url1));
// true
console.log(hasEmptyQuery(url2));
// false
I am designing a regular expression tester in HTML and JavaScript. The user will enter a regex, a string, and choose the function they want to test with (e.g. search, match, replace, etc.) via radio button and the program will display the results when that function is run with the specified arguments. Naturally there will be extra text boxes for the extra arguments to replace and such.
My problem is getting the string from the user and turning it into a regular expression. If I say that they don't need to have //'s around the regex they enter, then they can't set flags, like g and i. So they have to have the //'s around the expression, but how can I convert that string to a regex? It can't be a literal since its a string, and I can't pass it to the RegExp constructor since its not a string without the //'s. Is there any other way to make a user input string into a regex? Will I have to parse the string and flags of the regex with the //'s then construct it another way? Should I have them enter a string, and then enter the flags separately?
Use the RegExp object constructor to create a regular expression from a string:
var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);
or
var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);
Here is a one-liner: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
I got it from the escape-string-regexp NPM module.
Trying it out:
escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}
console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/
Using tagged template literals with flags support:
function str2reg(flags = 'u') {
return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
, flags)
}
function evalTemplate(strings, ...values) {
let i = 0
return strings.reduce((str, string) => `${str}${string}${
i < values.length ? values[i++] : ''}`, '')
}
console.log(str2reg()`example.com`)
// => /example\.com/u
Use the JavaScript RegExp object constructor.
var re = new RegExp("\\w+");
re.test("hello");
You can pass flags as a second string argument to the constructor. See the documentation for details.
In my case the user input somethimes was sorrounded by delimiters and sometimes not. therefore I added another case..
var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
// the parsed pattern had delimiters and modifiers. handle them.
var regexp = new RegExp(regParts[1], regParts[2]);
} else {
// we got pattern string without delimiters
var regexp = new RegExp(inputstring);
}
Try using the following function:
const stringToRegex = str => {
// Main regex
const main = str.match(/\/(.+)\/.*/)[1]
// Regex options
const options = str.match(/\/.+\/(.*)/)[1]
// Compiled regex
return new RegExp(main, options)
}
You can use it like so:
"abc".match(stringToRegex("/a/g"))
//=> ["a"]
Here is my one liner function that handles custom delimiters and invalid flags
// One liner
var stringToRegex = (s, m) => (m = s.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s);
// Readable version
function stringToRegex(str) {
const match = str.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/);
return match ?
new RegExp(
match[2],
match[3]
// Filter redundant flags, to avoid exceptions
.split('')
.filter((char, pos, flagArr) => flagArr.indexOf(char) === pos)
.join('')
)
: new RegExp(str);
}
console.log(stringToRegex('/(foo)?\/bar/i'));
console.log(stringToRegex('#(foo)?\/bar##gi')); //Custom delimiters
console.log(stringToRegex('#(foo)?\/bar##gig')); //Duplicate flags are filtered out
console.log(stringToRegex('/(foo)?\/bar')); // Treated as string
console.log(stringToRegex('gig')); // Treated as string
I suggest you also add separate checkboxes or a textfield for the special flags. That way it is clear that the user does not need to add any //'s. In the case of a replace, provide two textfields. This will make your life a lot easier.
Why? Because otherwise some users will add //'s while other will not. And some will make a syntax error. Then, after you stripped the //'s, you may end up with a syntactically valid regex that is nothing like what the user intended, leading to strange behaviour (from the user's perspective).
This will work also when the string is invalid or does not contain flags etc:
function regExpFromString(q) {
let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
if (flags === q) flags = '';
let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
try { return new RegExp(pattern, flags); } catch (e) { return null; }
}
console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));
Thanks to earlier answers, this blocks serves well as a general purpose solution for applying a configurable string into a RegEx .. for filtering text:
var permittedChars = '^a-z0-9 _,.?!#+<>';
permittedChars = '[' + permittedChars + ']';
var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);
log.debug ('strFilterRegEx: ' + strFilterRegEx);
strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!#+]/ig, '');
You can ask for flags using checkboxes then do something like this:
var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);
Safer, but not safe. (A version of Function that didn't have access to any other context would be good.)
const regexp = Function('return ' + string)()
I found #Richie Bendall solution very clean. I added few small modifications because it falls appart and throws error (maybe that's what you want) when passing non regex strings.
const stringToRegex = (str) => {
const re = /\/(.+)\/([gim]?)/
const match = str.match(re);
if (match) {
return new RegExp(match[1], match[2])
}
}
Using [gim]? in the pattern will ignore any match[2] value if it's invalid. You can omit the [gim]? pattern if you want an error to be thrown if the regex options is invalid.
I use eval to solve this problem.
For example:
function regex_exec() {
// Important! Like #Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk.
var regex = $("#regex").val();
// eval()
var patt = eval(userInput);
$("#result").val(patt.exec($("#textContent").val()));
}
I am designing a regular expression tester in HTML and JavaScript. The user will enter a regex, a string, and choose the function they want to test with (e.g. search, match, replace, etc.) via radio button and the program will display the results when that function is run with the specified arguments. Naturally there will be extra text boxes for the extra arguments to replace and such.
My problem is getting the string from the user and turning it into a regular expression. If I say that they don't need to have //'s around the regex they enter, then they can't set flags, like g and i. So they have to have the //'s around the expression, but how can I convert that string to a regex? It can't be a literal since its a string, and I can't pass it to the RegExp constructor since its not a string without the //'s. Is there any other way to make a user input string into a regex? Will I have to parse the string and flags of the regex with the //'s then construct it another way? Should I have them enter a string, and then enter the flags separately?
Use the RegExp object constructor to create a regular expression from a string:
var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);
or
var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);
Here is a one-liner: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
I got it from the escape-string-regexp NPM module.
Trying it out:
escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}
console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/
Using tagged template literals with flags support:
function str2reg(flags = 'u') {
return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
, flags)
}
function evalTemplate(strings, ...values) {
let i = 0
return strings.reduce((str, string) => `${str}${string}${
i < values.length ? values[i++] : ''}`, '')
}
console.log(str2reg()`example.com`)
// => /example\.com/u
Use the JavaScript RegExp object constructor.
var re = new RegExp("\\w+");
re.test("hello");
You can pass flags as a second string argument to the constructor. See the documentation for details.
In my case the user input somethimes was sorrounded by delimiters and sometimes not. therefore I added another case..
var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
// the parsed pattern had delimiters and modifiers. handle them.
var regexp = new RegExp(regParts[1], regParts[2]);
} else {
// we got pattern string without delimiters
var regexp = new RegExp(inputstring);
}
Try using the following function:
const stringToRegex = str => {
// Main regex
const main = str.match(/\/(.+)\/.*/)[1]
// Regex options
const options = str.match(/\/.+\/(.*)/)[1]
// Compiled regex
return new RegExp(main, options)
}
You can use it like so:
"abc".match(stringToRegex("/a/g"))
//=> ["a"]
Here is my one liner function that handles custom delimiters and invalid flags
// One liner
var stringToRegex = (s, m) => (m = s.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s);
// Readable version
function stringToRegex(str) {
const match = str.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/);
return match ?
new RegExp(
match[2],
match[3]
// Filter redundant flags, to avoid exceptions
.split('')
.filter((char, pos, flagArr) => flagArr.indexOf(char) === pos)
.join('')
)
: new RegExp(str);
}
console.log(stringToRegex('/(foo)?\/bar/i'));
console.log(stringToRegex('#(foo)?\/bar##gi')); //Custom delimiters
console.log(stringToRegex('#(foo)?\/bar##gig')); //Duplicate flags are filtered out
console.log(stringToRegex('/(foo)?\/bar')); // Treated as string
console.log(stringToRegex('gig')); // Treated as string
I suggest you also add separate checkboxes or a textfield for the special flags. That way it is clear that the user does not need to add any //'s. In the case of a replace, provide two textfields. This will make your life a lot easier.
Why? Because otherwise some users will add //'s while other will not. And some will make a syntax error. Then, after you stripped the //'s, you may end up with a syntactically valid regex that is nothing like what the user intended, leading to strange behaviour (from the user's perspective).
This will work also when the string is invalid or does not contain flags etc:
function regExpFromString(q) {
let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
if (flags === q) flags = '';
let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
try { return new RegExp(pattern, flags); } catch (e) { return null; }
}
console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));
Thanks to earlier answers, this blocks serves well as a general purpose solution for applying a configurable string into a RegEx .. for filtering text:
var permittedChars = '^a-z0-9 _,.?!#+<>';
permittedChars = '[' + permittedChars + ']';
var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);
log.debug ('strFilterRegEx: ' + strFilterRegEx);
strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!#+]/ig, '');
You can ask for flags using checkboxes then do something like this:
var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);
Safer, but not safe. (A version of Function that didn't have access to any other context would be good.)
const regexp = Function('return ' + string)()
I found #Richie Bendall solution very clean. I added few small modifications because it falls appart and throws error (maybe that's what you want) when passing non regex strings.
const stringToRegex = (str) => {
const re = /\/(.+)\/([gim]?)/
const match = str.match(re);
if (match) {
return new RegExp(match[1], match[2])
}
}
Using [gim]? in the pattern will ignore any match[2] value if it's invalid. You can omit the [gim]? pattern if you want an error to be thrown if the regex options is invalid.
I use eval to solve this problem.
For example:
function regex_exec() {
// Important! Like #Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk.
var regex = $("#regex").val();
// eval()
var patt = eval(userInput);
$("#result").val(patt.exec($("#textContent").val()));
}
I am having a case where i need to split given string using starts with regex (/^'searchString'/) which is not working such as
"token=123412acascasdaASDFADS".split('token=')
Here i want to extract the token value but as there might be some other possible parameters such as
"reset_token=SDFDFdsf12313ADADF".split('token=')
Here it also split the string with 'token=', Thats why i need to split the string using some regex which states that split the string where it starts with given string.
Thanks..
EDITED
Guys thanks for your valuable response this issue can be resolve using /\btoken=/ BUT BUT its does not work if 'token=' stored as a string into a variable such as
sParam = 'token=';
"token=123412acascasdaASDFADS".split(/\bsParam/);
This does not works.
You can use regex in split with word boundary:
"token=123412acascasdaASDFADS".split(/\btoken=/)
If token is stored in a variable then use RegExp constructor:
var sParam = "token";
var re = new RegExp("\\b" + sParam + "=");
Then use it:
var tokens = "token=123412acascasdaASDFADS".split( re );
This is the use case for the \b anchor:
\btoken=
It ensures there's no other word character before token (a word character being [a-zA-Z0-9_])
You need to split the string using the & parameter delimiter, then loop through those parameters:
var token;
$.each(params.split('&'), function() {
var parval = this.split('=');
if (parval[0] == "token") {
token = parval[1];
return false; // end the $.each loop
}
});
if you just use token= as the split delimiter, you'll include all the other parameters after it in the value.
It's not clear what you need, but this may be an idea to work with?
var reqstr = "token=12345&reset_token=SDFDFdsf12313ADADF&someval=foo"
.split(/[&=]/)
,req = [];
reqstr.map( function (v, i) {
if (i%2==0) {
var o = {};
o[/token/i.test(v) ? 'token' : v] = reqstr[i+1];
this.push(o);
} return v
}, req);
/* => req now contains:
[ { token: '12345' },
{ token: 'SDFDFdsf12313ADADF' },
{ someval: 'foo' } ]
*/
You can try with String#match() function and get the matched group from index 1
sample code
var re = /^token=(.*)$/;
var str = 'token=123412acascasdaASDFADS';
console.log('token=123412acascasdaASDFADS'.match('/^token=(.*)$/')[1]);
output:
123412acascasdaASDFADS
If token is dynamic then use RegExp
var token='token=';
var re = new RegExp("^"+token+"(.*)$");
var str = 'token=123412acascasdaASDFADS';
console.log(str.match(re)[1]);
Learn more...
I'm making a small web app in which a user enters a server URL from which it pulls a load of data with an AJAX request.
Since the user has to enter the URL manually, people generally forget the trailing slash, even though it's required (as some data is appended to the url entered). I need a way to check if the slash is present, and if not, add it.
This seems like a problem that jQuery would have a one-liner for, does anyone know how to do this or should I write a JS function for it?
var lastChar = url.substr(-1); // Selects the last character
if (lastChar != '/') { // If the last character is not a slash
url = url + '/'; // Append a slash to it.
}
The temporary variable name can be omitted, and directly embedded in the assertion:
if (url.substr(-1) != '/') url += '/';
Since the goal is changing the url with a one-liner, the following solution can also be used:
url = url.replace(/\/?$/, '/');
If the trailing slash exists, it is replaced with /.
If the trailing slash does not exist, a / is appended to the end (to be exact: The trailing anchor is replaced with /).
url += url.endsWith("/") ? "" : "/"
I added to the regex solution to accommodate query strings:
http://jsfiddle.net/hRheW/8/
url.replace(/\/?(\?|#|$)/, '/$1')
This works as well:
url = url.replace(/\/$|$/, '/');
Example:
let urlWithoutSlash = 'https://www.example.com/path';
urlWithoutSlash = urlWithoutSlash.replace(/\/$|$/, '/');
console.log(urlWithoutSlash);
let urlWithSlash = 'https://www.example.com/path/';
urlWithSlash = urlWithSlash.replace(/\/$|$/, '/');
console.log(urlWithSlash);
Output:
https://www.example.com/path/
https://www.example.com/path/
It replaces either the trailing slash or no trailing slash with a trailing slash. So if the slash is present, it replaces it with one (essentially leaving it there); if one is not present, it adds the trailing slash.
You can do something like:
var url = 'http://stackoverflow.com';
if (!url.match(/\/$/)) {
url += '/';
}
Here's the proof: http://jsfiddle.net/matthewbj/FyLnH/
The URL class is pretty awesome - it helps us change the path and takes care of query parameters and fragment identifiers
function addTrailingSlash(u) {
const url = new URL(u);
url.pathname += url.pathname.endsWith("/") ? "" : "/";
return url.toString();
}
addTrailingSlash('http://example.com/slug?page=2');
// result: "http://example.com/slug/?page=2"
You can read more about URL on MDN
Before finding this question and it's answers I created my own approach. I post it here as I don't see something similar.
function addSlashToUrl() {
//If there is no trailing shash after the path in the url add it
if (window.location.pathname.endsWith('/') === false) {
var url = window.location.protocol + '//' +
window.location.host +
window.location.pathname + '/' +
window.location.search;
window.history.replaceState(null, document.title, url);
}
}
Not every URL can be completed with slash at the end. There are at least several conditions that do not allow one:
String after last existing slash is something like index.html.
There are parameters: /page?foo=1&bar=2.
There is link to fragment: /page#tomato.
I have written a function for adding slash if none of the above cases are present. There are also two additional functions for checking the possibility of adding slash and for breaking URL into parts. Last one is not mine, I've given a link to the original one.
const SLASH = '/';
function appendSlashToUrlIfIsPossible(url) {
var resultingUrl = url;
var slashAppendingPossible = slashAppendingIsPossible(url);
if (slashAppendingPossible) {
resultingUrl += SLASH;
}
return resultingUrl;
}
function slashAppendingIsPossible(url) {
// Slash is possible to add to the end of url in following cases:
// - There is no slash standing as last symbol of URL.
// - There is no file extension (or there is no dot inside part called file name).
// - There are no parameters (even empty ones — single ? at the end of URL).
// - There is no link to a fragment (even empty one — single # mark at the end of URL).
var slashAppendingPossible = false;
var parsedUrl = parseUrl(url);
// Checking for slash absence.
var path = parsedUrl.path;
var lastCharacterInPath = path.substr(-1);
var noSlashInPathEnd = lastCharacterInPath !== SLASH;
// Check for extension absence.
const FILE_EXTENSION_REGEXP = /\.[^.]*$/;
var noFileExtension = !FILE_EXTENSION_REGEXP.test(parsedUrl.file);
// Check for parameters absence.
var noParameters = parsedUrl.query.length === 0;
// Check for link to fragment absence.
var noLinkToFragment = parsedUrl.hash.length === 0;
// All checks above cannot guarantee that there is no '?' or '#' symbol at the end of URL.
// It is required to be checked manually.
var NO_SLASH_HASH_OR_QUESTION_MARK_AT_STRING_END_REGEXP = /[^\/#?]$/;
var noStopCharactersAtTheEndOfRelativePath = NO_SLASH_HASH_OR_QUESTION_MARK_AT_STRING_END_REGEXP.test(parsedUrl.relative);
slashAppendingPossible = noSlashInPathEnd && noFileExtension && noParameters && noLinkToFragment && noStopCharactersAtTheEndOfRelativePath;
return slashAppendingPossible;
}
// parseUrl function is based on following one:
// http://james.padolsey.com/javascript/parsing-urls-with-the-dom/.
function parseUrl(url) {
var a = document.createElement('a');
a.href = url;
const DEFAULT_STRING = '';
var getParametersAndValues = function (a) {
var parametersAndValues = {};
const QUESTION_MARK_IN_STRING_START_REGEXP = /^\?/;
const PARAMETERS_DELIMITER = '&';
const PARAMETER_VALUE_DELIMITER = '=';
var parametersAndValuesStrings = a.search.replace(QUESTION_MARK_IN_STRING_START_REGEXP, DEFAULT_STRING).split(PARAMETERS_DELIMITER);
var parametersAmount = parametersAndValuesStrings.length;
for (let index = 0; index < parametersAmount; index++) {
if (!parametersAndValuesStrings[index]) {
continue;
}
let parameterAndValue = parametersAndValuesStrings[index].split(PARAMETER_VALUE_DELIMITER);
let parameter = parameterAndValue[0];
let value = parameterAndValue[1];
parametersAndValues[parameter] = value;
}
return parametersAndValues;
};
const PROTOCOL_DELIMITER = ':';
const SYMBOLS_AFTER_LAST_SLASH_AT_STRING_END_REGEXP = /\/([^\/?#]+)$/i;
// Stub for the case when regexp match method returns null.
const REGEXP_MATCH_STUB = [null, DEFAULT_STRING];
const URL_FRAGMENT_MARK = '#';
const NOT_SLASH_AT_STRING_START_REGEXP = /^([^\/])/;
// Replace methods uses '$1' to place first capturing group.
// In NOT_SLASH_AT_STRING_START_REGEXP regular expression that is the first
// symbol in case something else, but not '/' has taken first position.
const ORIGINAL_STRING_PREPENDED_BY_SLASH = '/$1';
const URL_RELATIVE_PART_REGEXP = /tps?:\/\/[^\/]+(.+)/;
const SLASH_AT_STRING_START_REGEXP = /^\//;
const PATH_SEGMENTS_DELIMITER = '/';
return {
source: url,
protocol: a.protocol.replace(PROTOCOL_DELIMITER, DEFAULT_STRING),
host: a.hostname,
port: a.port,
query: a.search,
parameters: getParametersAndValues(a),
file: (a.pathname.match(SYMBOLS_AFTER_LAST_SLASH_AT_STRING_END_REGEXP) || REGEXP_MATCH_STUB)[1],
hash: a.hash.replace(URL_FRAGMENT_MARK, DEFAULT_STRING),
path: a.pathname.replace(NOT_SLASH_AT_STRING_START_REGEXP, ORIGINAL_STRING_PREPENDED_BY_SLASH),
relative: (a.href.match(URL_RELATIVE_PART_REGEXP) || REGEXP_MATCH_STUB)[1],
segments: a.pathname.replace(SLASH_AT_STRING_START_REGEXP, DEFAULT_STRING).split(PATH_SEGMENTS_DELIMITER)
};
}
There might also be several cases when adding slash is not possible. If you know some, please comment my answer.
For those who use different inputs: like http://example.com or http://example.com/eee. It should not add a trailling slash in the second case.
There is the serialization option using .href which will add trailing slash only after the domain (host).
In NodeJs,
You would use the url module like this:
const url = require ('url');
let jojo = url.parse('http://google.com')
console.log(jojo);
In pure JS, you would use
var url = document.getElementsByTagName('a')[0];
var myURL = "http://stackoverflow.com";
console.log(myURL.href);