JavaScript, include string not included with special characters - javascript

I'm trying to ignore some string.
The idea is to check if the string to ignore is included in a list of strings separated by commas. When the string to ignore is "/healthCheck' (case 2) works ok, but in case 1, when the string has more special characters, is not working.
Playground: https://jsfiddle.net/pmiranda/pwfLou6e/7/
const URLS_TO_IGNORE="/healthCheck,/socket.io//?EIO,/socket.io, /otherEndpoint"
// Case 1 not working
const endpointToIgnore = '/socket.io//?EIO=4&transport=polling&t=77qQ9HboF54_NtCdAAb';
const ignoreLogger = URLS_TO_IGNORE.includes(endpointToIgnore);
console.log(ignoreLogger); // false
// Case 2 working
const endpointToIgnore2 = '/healthCheck';
const ignoreLogger2 = URLS_TO_IGNORE.includes(endpointToIgnore2);
console.log(ignoreLogger2); // true
// Case 3 working
const endpointToIgnore3 = '/otherEndpoint';
const ignoreLogger3 = URLS_TO_IGNORE.includes(endpointToIgnore2);
console.log(ignoreLogger3); // true
How can Ignore the string: /socket.io ?
I need a way to valid that every string that starts with /socket.io despite what other characters are after, be included in the ignore function.

use the test() method of the regular expression to check if the string matches the pattern that starts with "/socket.io"
const URLS_TO_IGNORE = "/healthCheck,/socket.io//?EIO=4&transport=polling&t=77qQ9HboF54_NtCdAAb,/socket.io, /otherEndpoint";
// Case 1 working
const endpointToIgnore = '/socket.io//?EIO=4&transport=polling&t=OPVH0sr&sid=77qQ9HboF54_NtCdAAb';
const ignoreLogger = URLS_TO_IGNORE.split(",").some(url => /^\/socket\.io.*/.test(url) && endpointToIgnore.includes(url) );
console.log(ignoreLogger); // true
// Case 2 working
const endpointToIgnore2 = '/healthCheck';
const ignoreLogger2 = URLS_TO_IGNORE.includes(endpointToIgnore2);
console.log(ignoreLogger2); // true
// Case 3 working
const endpointToIgnore3 = '/otherEndpoint';
const ignoreLogger3 = URLS_TO_IGNORE.includes(endpointToIgnore2);
console.log(ignoreLogger3); // true

Take a look at startsWith https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith You could split your URLS_TO_IGNORE by commas to get an array and check if the endpointToIgnore starts with any of them
const URLS_TO_IGNORE="/healthCheck,/socket.io//?EIO,/socket.io, /otherEndpoint".split(',')
const endpointToIgnore = '/socket.io//?EIO=4&transport=polling&t=OPVH0sr&sid=77qQ9HboF54_NtCdAAb'
const ignoreLogger = URLS_TO_IGNORE.some((path)=>endpointToIgnore.startsWith(path));

You can make a dummy URL and look at the pathname
const URLS_TO_IGNORE = ["/healthCheck","/socket.io","/otherEndpoint"];
const checkUrl = path => {
const url = new URL(`https://dummyURL.com${path}`);
const pathname = url.pathname;
const ignore = URLS_TO_IGNORE.some(pn => pathname.startsWith(pn))
console.log("PN:",pathname,"\nign",ignore)
return ignore
};
console.log(checkUrl('/socket.io//?EIO=4&transport=polling&t=OPVH0sr&sid=77qQ9HboF54_NtCdAAb'));
console.log(checkUrl('/socket.io/?EIO=4&transport=polling&t=OPVH0sr&sid=77qQ9HboF54_NtCdAAb'));
console.log(checkUrl('/okendpoint'));
console.log(checkUrl('/healthCheck'));
console.log(checkUrl('/otherEndpoint'));

let text = "";
const check_urls = ['/socket.io//?EIO=4&transport=polling&t=OPVH0sr&sid=77qQ9HboF54_NtCdAAb','/healthCheck']
const urs= '/socket.io//?EIO=4&transport=polling&t=OPVH0sr&sid=77qQ9HboF54_NtCdAAb';
check_urls.forEach(ifun);
function ifun(item, index) {
text += index + ": " + item +" == "+ urs.includes(item);
}
console.log(text);

Related

Lowercase everything after firts appearance of the character in a string in JS

Lowercase everything after firts appearance of the character in a string in JS
One option is using regular expression:
str.replace(/\.([^.]*?)$/, (m) => m.toLowerCase())
What you can do is splitting the string at ".", then convert the last part .toLowerCase() and finally .join() everything back together.
const t = 'qwery.ABC.ABC';
const parts = t.split(".");
console.log(parts.slice(0, -1).join(".") + "." + parts[parts.length - 1].toLowerCase());
One could argue whether that would actually be a cleaner variant. What usually isn't a bad idea for code readability is writing a utility function for that use case.
const t = "qwery.ABC.ABC";
const lastBitToLowerCase = (text, separator) => {
const parts = t.split(separator);
return `${parts.slice(0, -1).join(separator)}${separator}${parts[
parts.length - 1
].toLowerCase()}`;
};
const result = lastBitToLowerCase(t, "."); // "qwery.ABC.abc"
Regex using negative lookahead:
const re = /\.((?:.(?!\.))+)$/;
const inputs = [
"qwerty.ABC.ABC",
"yuiop.uu",
"QWERT.YUIOP"
];
inputs.forEach(input => {
const result = input.replace(re, x => x.toLowerCase());
console.log(input, "-->", result);
});
Regex described here: https://regexr.com/6qk6r

How to check if string has vowels? [duplicate]

This question already has answers here:
Counting the vowels in a string using Regular Expression
(2 answers)
Closed 1 year ago.
I tried to write a function which checks if a given string contains vowels and I cannot see why it works for some words 'cat' and 'why' but not 'DOG', i believe that i have accounted for uppercase.
const containsVowels = string => {
var lowerCase = string.toLowerCase();
var word = lowerCase.split("");
var vowelsArray = ["a","o","i","u","y"];
const result = word.filter(letter => vowelsArray.includes(letter));
return result.includes("a","o","i","u","y");
};
includes takes only 2 parameters, the first one being searchElement and second parameter being fromIndex.
Reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes#parameters
You wouldn't want to do the last check if the result array contains vowels or not, because in the previous step itself you are filtering out the word to get array that contains only vowels. So just check if the array is empty or it contains any elements inside it.
const containsVowels = str => {
let lowerCase = str.toLowerCase();
let word = lowerCase.split("");
let vowelsArray = ["a","o","i","u","y"];
const result = word.filter(letter => vowelsArray.includes(letter));
return result.length > 0;
};
console.log(containsVowels("cat"));
console.log(containsVowels("DOG"));
console.log(containsVowels("BCDF"));
Suggestion: Don't use built in keywords as variables.
As pointed out by Muhammad, we can regex to find if the string contains vowels
const containsVowel = str => {
const vowelRegex = /[aeiou]/i;
return vowelRegex.test(str);
};
2 Problems,
Why would you use includes twice ?
&
You cannot use includes like
result.includes("a","o","i","u","y");
includes only accepts 2 param:
includes(searchElement, fromIndex)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
By filtering, you already know the result.
What you should do is, compare the length of the result:
const containsVowels = string => {
let lowerCase = string.toLowerCase();
let word = lowerCase.split("");
let vowelsArray = ["a","o","i","u","y"];
const result = word.filter(letter => vowelsArray.includes(letter));
return result.length > 0 ? true : false
};
use regex to get the result.
var regEx = /[aeiou]/gi
var test_string = "Cat";
var match = test_string.match(regEx)
if(match)
console.log("Match found", match)
when you write something like this
result.includes("a","o","i","u","y")
this compare with only it's first element which is "a" and one thing you don't need to write the above mentioned code further.
After filtering just replace the above code with
return result.length > 0 ? true : false

check if substring exist in string

I want to check if a sub string is included in a string, but the sub string contains a number, this number can change. I used RegExp but it's not working
let url = "http://localhost:8080/api/issue/board/537/sprint";
url.includes('/issue/board/537/sprint'); // true
the value 537 can change
var reg = new RegExp('^[0-9]+$');
url.includes('/issue/board/' + reg +'/sprint'); // false
That's not how you use Regex.
Create an expression:
const reg = new RegExp('/issue/board/[0-9]+/sprint');
And test it against your url:
const url = "http://localhost:8080/api/issue/board/537/sprint";
const matches = url.test(reg); // true
const reg = new RegExp('/issue/board/[0-9]+/sprint');
const url = "http://localhost:8080/api/issue/board/537/sprint";
const matches = url.match(reg);
console.log(matches ? true: false)
var reg = new RegExp('/issue/board/[0-9]+/sprint')
const regex = new RegExp('\/board\/(.*?)\/sprint');
const url = 'http://localhost:8080/api/issue/board/537/sprint';
const test = regex.test(url);
const matches = regex.exec(url);
console.log(test); // true
console.log(matches[1]); //537
const condition = new RegExp('\/issue\/board\/[0-9]+\/sprint').test('http://localhost:8080/api/issue/board/537/sprint'); // true
Easiest way is just to use indexOf. Like so
let url = "http://localhost:8080/api/issue/board/537/sprint",
match = '/issue/board/537/sprint';
if (url.indexOf(match) !== -1) {
// true
} else {
// false
}
The indexOf a string that isn't contained in the string you're checking will always be -1

Overlapping named capturing groups

I'm using named capturing groups to validate and extract data out of a product number. The format of the product number looks like this:
1102961D048.075
Chars 1-2 gender_code 11
Chars 1-6 style 110296
Chars 7-8 width_code 1D
Chars 9-11 color_code 048
Char 12 delimiter ignored
Chars 13-15 size_code 075
My current code looks like this:
const validateMpn = (mpn) => {
const regex = /(?<style>\d{6})(?<width>\d{1}[ABDE])(?<color_code>\d{3})\.(?<size_code>\d{3})/gi
const match = regex.exec(mpn)
if (!match) {
return null
}
return match.groups
}
const str1 = '1102961D048.075'
const str2 = '1200322A001.085'
const match1 = validateMpn(str1)
const match2 = validateMpn(str2)
console.log(match1)
console.log(match2)
As gender_code and style overlap I'm not sure how to get them both. Therefore I have the following questions:
Is it possible to this with only one regular expression?
If yes, how could I accomplish this?
Sure, just place gender inside the style group:
const validateMpn = (mpn) => {
const regex = /(?<style>(?<gender>\d{2})\d{4})(?<width>\d{1}[ABDE])(?<color_code>\d{3})\.(?<size_code>\d{3})/gi
const match = regex.exec(mpn)
if (!match) {
return null
}
return match.groups
}
const str1 = '1102961D048.075'
const str2 = '1200322A001.085'
const match1 = validateMpn(str1)
const match2 = validateMpn(str2)
console.log(match1)
console.log(match2)
I suggest just having separate capture groups for the first two and four following characters. Then, form the style by just concatenating together the first two capture groups:
var input = "1102961D048.075";
var regex = /(.{2})(.{4})(.{2})(.{3}).(.{3})/g;
var match = regex.exec(input);
console.log("gender_code: " + match[1]);
console.log("style: " + match[1] + match[2]);
As a style note, I prefer not using named capture groups, because they tend to result in a bloated regex which is hard to read.
Yes you can capture gender_code using positive look ahead using this regex,
(?=(..))(\d{6})(\d{1}[ABDE])(\d{3})\.(\d{3})
Regex Demo
This is named groups regex but will only work in Chrome browser
and named capture grouping will be available in ECMAScript 2018 and is only supported in Chrome as of now.
This JS demo will work in Chrome as that is the only one as of now supporting EcmaScript2018,
const validateMpn = (mpn) => {
const regex = /(?=(?<gender_code>\d\d))(?<style>\d{6})(?<width>\d{1}[ABDE])(?<color_code>\d{3})\.(?<size_code>\d{3})/gi
const match = regex.exec(mpn)
if (!match) {
return null
}
return match.groups
}
const str1 = '1102961D048.075'
const str2 = '1200322A001.085'
const match1 = validateMpn(str1)
const match2 = validateMpn(str2)
console.log(match1)
console.log(match2)

How to match identical strings in Javascript?

Take these two urls:
const url1 = '/user/{username}/edit'
const url2 = '/user/harry/edit'
Is there a solution to match these two urls and return true as they are similar?
I tried the following and should be the worst solution:
const url1 = '/user/{username}/edit'
const url2 = '/user/harry/edit'
const split1 = url1.split('/')
const split2 = url2.split('/')
let matchCount = 0
let notMatchedCount = 0
split1.map(x => {
if(x === split2[x]) {
matchCount++
} else {
notMatchedCount++
}
})
if(matchCount > notMatchedCount) {
console.log('Match Found')
} else {
console.log('Match not found')
}
EDIT
Solution was to use PathToRegExp package! Thanks to #ChiragRavindra!
You could use a regex to test the url
\/user\/ matching /user/
\w+ matching 1 or more word characters ([a-zA-Z0-9_]+)
\/edit matching /edit
const url1 = '/user/{username}/edit';
const urlCorrect = '/user/harry/edit';
const urlWrong = '/users/harry/edit';
//generate a regex string by escaping the slashes and changing word between curly brackets with {\w+}
var regexString = url1.replace(/\{\w+\}/g, '\\w+').replace(/\//g, '\\/');
console.log('generating regex: ' + regexString);
var regex = new RegExp(regexString);
//test using the generated regex
console.log(regex.test(urlCorrect));
console.log(regex.test(urlWrong));
I would suggest you to look inside this library
NPM - String similarity library
Library simply returns the probability of comparing two strings if they're similar.
Then it's all on you to set up the threshold from how many percentages you assume that they're the same.

Categories