Convert String in the Parenthesis in the URL To Query Parameters: Javascript - javascript

I want to convert the string in {} in search URL to query parameters which would help users capture search terms in web analytics tools.
Here's what I am trying to do, Let's say
Search URL is:
example.com/search/newyork-gyms?dev=desktop&id=1220391131
User Input will be:
var search_url_format = '/search/{city}-{service}
Output URL:
example.com/search?city=newyork&service=gyms&dev=desktop&id=1220391131
The problem is when is use the regex {(.*)} it captures the whole string {city}-{service}.
But I what I want is [{city},{service}].
The URL format can also be like
search/{city}/{service}/
search/{city}_{service}/
What I have tried is for a single variable.
It returns correct output.
Eg: URL:/search/newyork
User Input: /search/{city}
Output: /search/newyork?city=newyork
URL: /search-germany
User Input: /search-{country}
Output: /search-germany?country=germany
var search_url_format = '/search/{city}' //User Enters any variable in brackets
var urloutput = '/search/newyork' //Demo URL
//Log output
console.log(URL2Query(search_url_format)) //Output: '/search/newyork?city=newyork'
function URL2Query(url) {
var variableReg = new RegExp(/{(.*)}/)
var string_url = variableReg.exec(url)
var variable1 = string_url[0]
//Capture the variable
var reg = new RegExp(url.replace(variable1, '([^\?|\/|&]+)'))
var search_string = reg.exec(urloutput)[1]
if (location.search.length > 0) // if no query parameters
{
return urloutput + "?" + string_url[1] + "=" + search_string
} else {
return urloutput + "&" + string_url[1] + "=" + search_string
}
}

You are missing two things:
parenthesis to match groups and you use .* which includes "{" sign.
So can use match instead of exec like this:
var search_url_format = '/search/{city}-{service}' //User Enters any
var variableReg = new RegExp(/({\w+})/g)
var string_url = url.match(variableReg); // [{city}, {service}]

You can probably assume your "variable" will be alphanumeric instead of any character. With this assumption "{", "-", "_" etc will be punctuation.
so your grouping regexp could be /({\w+})/g.
//example
const r = /({\w+})/g;
let variable;
const url = '/search/{city}-{service}';
while ((variable = r.exec(url)) !== null) {
let msg = 'Found ' + variable[0] + '. ';
msg += 'Next match starts at ' + r.lastIndex;
console.log(msg);
}

Related

Matching cookie string in Javascript with regex

For simplicity sake, I am looking to match a cookie in JavaScript with two groups. This is so I can loop through the results in a key, pair order.
I am testing with this string:
_ga_GZ83393=NOTGOOGLE.1.1613155331397.4.1.12345678.4; _ga=GA5.2.14144141.1135335686424; test=bob
So far I have come up with /(\w+)=(\w+)/ but it is failing with the periods that are in the Google analytic cookies.
NOTE: The Google Analytic values are spoofed, keeping the same format but as to not cause security issues.
You can scan up to the next ; or end of string:
/(\w+)=([^;]*)/
You could use split and a regex to pick the key & value pairs:
const cookies = '_ga_GZ83393=NOTGOOGLE.1.1613155331397.4.1.12345678.4; _ga=GA5.2.14144141.1135335686424; test=bob';
const regex = /^ *([^=]*)=(.*)$/;
cookies.split(/;/).forEach(item => {
let key = item.replace(regex, '$1');
let val = item.replace(regex, '$2');
console.log('key: ' + key + ', val: ' + val);
});
Output:
key: _ga_GZ83393, val: NOTGOOGLE.1.1613155331397.4.1.12345678.4
key: _ga, val: GA5.2.14144141.1135335686424
key: test, val: bob
/((?<index>\w+)=(?<value>[\w\.0-9]+))/g
Thanks to #Peter Thoeny to point out that the named groups are not supported in all browsers, so here is the version without it.
/((\w+)=([\w\.0-9]+))/g
https://regex101.com/r/lWpbgz/1
var cookie = "_ga_GZ83393=NOTGOOGLE.1.1613155331397.4.1.12345678.4; _ga=GA5.2.14144141.1135335686424; test=bob";
var match = null;
var regex = /((?<index>\w+)=(?<value>[\w\.0-9]+))/g;
var div = document.querySelector("#result");
match = regex.exec(cookie);
while(match != null) {
div.innerText += match.groups.index + " = " + match.groups.value + "\n";
console.log(match.groups.index + " = " + match.groups.value);
match = regex.exec(cookie);
}
<div id="result"></div>

Using Javascript, .test and RegEx to evaluate a URL for /?s=

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

How to check for Forward Slash within this Regex for all special characters?

I am trying to find a regex solution to check if a string matches all conditions + / forward slashes.
Current code:
var specialChars = /^[a-zA-Z0-9!##\$%\^\&*\)\(+=._-]+$/g;
This will match true if a string looks like so: 4!##$.
However it does not work if the string looks like this: 5/6/2019
This is how I'm implementing this check, basically I have a function that takes in an long string. And what I'm trying to do is pluck out the tracking ID then create a link out of it.
My test cases are also in the demo, the date test is the one that fails, since the linkCreator function ends up linking to the date:
https://jsfiddle.net/cojuevp5/
var linkCreator = function(value) {
var strings = value.split(' ');
var aHref = '<a href="http://www.google.com/search?q=';
var targetBlank = '" target="_blank" style="text-decoration: underline">';
var trackingString = strings.reduce(function(prevVal, currVal, idx) {
var specialChars = /^[a-zA-Z0-9!##\$%\^\&*\)\(+=._-]+$/g;
// Does val start with number and not contain special characters including /
var link = currVal.match(/^\d/) && !currVal.match(specialChars) ?
aHref + currVal + targetBlank + currVal + '</a>' :
currVal;
return idx == 0 ? link : prevVal + ' ' + link;
}, '');
console.log(trackingString);
}
const case1 = '434663008870'
const case2 = '4S4663008870'
const case3 = '4S4663008870 PS'
const case4 = 'SHD FX 462367757727 PS'
const case5 = 'SHD FX 429970755485, R'
const case6 = 'SHD HEADER TRACKING PS'
const case7 = 'N/A'
const case8 = 'AF SHD FX 462367757727 PS'
const case9 = '4/7/2019'
const case10 = '4!##$%^&'
const value = case9
const link = linkCreator(value)
console.log(link)
You might want to add a \/ and that would likely solve your problem:
^([A-z0-9!\/##$%^&*)(+=._-]+)$
Just like Barmar says, you do not need to escape all chars inside []:
I'm guessing that this may be what you might want to match:
You might just use this tool and design any expression that you wish.
Graph
This graph shows how your expression works:

Javascript string trimming: Url and file path

Here comes javascript noob again.
What I would like to do. 1:
// I will have many URLs as input
// I want to check if URL NOT end with slash
// if not then trim string after slash
var given_URL = "http://www.test.com/test"
var trimmed_URL = "http://www.test.com/"
What I would like to do. 2:
// I will have many file paths
// I would like to check if the path starts with unwanted dot OR slash
// If so, I would like to trim it
var given_path_1 = "./folder/filename.xxx"
var given_path_2 = "/folder/filename.xxx"
var given_path_3 = ".folder/filename.xxx"
var trimmed_path = "folder/filename.xxx"
I would like to know how to achieve these.
Thanks in advance
For your first question, you should use the lastIndexOf method.
For example:
var index = given_URL.lastIndexOf("/");
Check if index === given_URL.length - 1 is true. If it is, you can use the slice method to cut your url.
For example:
var newUrl = given_URL.slice(0,index);
For your second question, you can check if given_URL[0] === "." or given_URL[0] === "/". If this is true, then use the slice method to slice it.
For example:
var newUrl = given_URL.slice(1, given_URL.length - 1);
You should try to use replace() using some regex:
//replace all "/*" at the end with "/"
given_URL.replace(/\/\w+$/,'/');
//replace all non letters at the start with ""
given_path_2.replace(/^\W+/,'');
To trim until the last forward slash /, you could find the last occurrence of it and check if it the last letter in the string. If it is, you take the string until after that last occurrence.
To remove an optional dot (\.?), followed by an optional forward slash (\/?) from the start (^) of a string, you could do a replace with a regex of ^\.?\/?.
function trimToLastForwardslash(input) {
var lastBackSlash = input.lastIndexOf('/');
return lastBackSlash != -1 && lastBackSlash != input.length - 1 ? input.substring(0, lastBackSlash + 1) : input;
}
function trimFirstDotOrForwardSlash(input) {
return input.replace(/^\.?\/?/, '');
}
var path = "http://www.test.com/test";
console.log(path + ' => trim last slash => ' + trimToLastForwardslash(path));
path = "http://www.test.com/test/";
console.log(path + ' => trim last slash => ' + trimToLastForwardslash(path));
path = "./folder/filename.xxx";
console.log(path + ' => trim first dot or slash => ' + trimFirstDotOrForwardSlash(path));
path = "/folder/filename.xxx";
console.log(path + ' => trim first dot or slash => ' + trimFirstDotOrForwardSlash(path));
path = ".folder/filename.xxx";
console.log(path + ' => trim first dot or slash => ' + trimFirstDotOrForwardSlash(path));

javascript regex ending string with values in array

I've to check if my string value is ending with ".com" or ".de"
I've put this values inside array:
var valuesEnd = [".com", ".de"]
My value to compare is taken from form. Also it has to check for # sign, it must have.
Use RegExp#test.
var str = ['abc.de', 'wok.pl', 'qwdok.com'];
console.log(str.map(v => /\w+\.(de|com)$/g.test(v) ? v + ' is valid' : v + ' is invalid'));
You can use a regular expression like this:
var str = prompt("Email: ");
if(/\.(?:com|de)$/.test(str))
alert("'" + str + "' is valid");
else
alert("'" + str + "' is not valid");
I've created a jQuery plugin for you:
(function($) {
// the string object (NOTE: it can be extended)
$.string = {};
// "create" a new string
$.string.new = function(string) {
return string;
};
// test a string for a regex match
$.string.test = function(string, regex) {
return regex.test(string);
};
// join three strings together
$.string.join = function(a, b, c) {
return a + b + c;
};
// log a string to the console
$.string.log = function(string) {
console.log(string);
};
})(jQuery);
Then you would use the plugin like this:
// for test purposes we'll be using: "example#example.com"
var email = $.string.new("example#example.com");
// check to see if the email is valid or not
if($.string.test(email, /\#.*?\.(?:com|de)$/)) {
// let us know that the email is valid
$.string.log($.string.join("'", email, "' is a valid email."));
}
// if this block runs the email is invalid
else {
// let us know that this is an invalid email
$.string.log($.string.join("'", email, "' is not a valid email."));
}

Categories

Resources