Javascript node.js regex url matching - javascript

So pretty much I have an inputted URL and I am trying to see if it starts with any of the following URLs:
"https://open.spotify.com/playlist/",
"https://www.youtube.com/watch",
"https://youtu.be/",
"https://open.spotify.com/track/",
"https://youtube.com/playlist",
So how it should work is if I were to input "https://open.spotify.com/track/1vrd6UOGamcKNGnSHJQlSt?si=61680eaef0ac419e" it would return that it matched "https://open.spotify.com/track/".
If I were to input "https://youtu.be/5qap5aO4i9A" it would return "https://youtu.be/".
So far I have
url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)
url.match(/^(https?:\/\/)?(www\.)?(m\.)?(youtube\.com|youtu\.?be)\/.+$/gi)
but it's not taking me down the right path and I am extremely lost. Thank you!

Since you need to get the specific prefix that matched, checking with startsWith would probably be simpler than using a regular expression:
const prefixes = [
"https://open.spotify.com/playlist/",
"https://www.youtube.com/watch",
"https://youtu.be/",
"https://open.spotify.com/track/",
"https://youtube.com/playlist",
];
function getPrefix(url) {
const urlLower = url.toLowerCase();
return prefixes.find((prefix) => urlLower.startsWith(prefix));
}
getPrefix("https://open.spotify.com/track/1vrd6UOGamcKNGnSHJQlSt?si=61680eaef0ac419e"); // "https://open.spotify.com/track/"
getPrefix("https://youtu.be/5qap5aO4i9A"); // "https://youtu.be/"

You should not use regex for that purpose you are using. Since you have all the list of urls you have to match against. You just have to check with the url you receive.
const list = ["https://open.spotify.com/playlist/",
"https://www.youtube.com/watch",
"https://youtu.be/",
"https://open.spotify.com/track/",
"https://youtube.com/playlist",
];
function getMeMatchedURL(url) {
const matchedURL = list.filter(item => {
return url.substring(0, item.length) === item;
});
console.log(matchedURL);
}
getMeMatchedURL("https://open.spotify.com/track/1vrd6UOGamcKNGnSHJQlSt?si=61680eaef0ac419e");
getMeMatchedURL("https://youtu.be/5qap5aO4i9A");
From this you will get the url it matches, if it return empty array then it didn't match any of the list.

Related

How to take a part of a carrent url with cypress/javascript

how can i extract the id from this link ? .localhost/survey/20?vbpCategoryId
my code is:
cy.url().then(URL => {
const current_url = URL.split('/');
cy.log(current_url[nr]);
cy.wrap(current_url[nr]).as('alias');
if it was between "/" it was easy but in this case it is between "/" and "?"
Thanks!
If your URL will always be formed similar to as you explained, we can use .split() and .pop() to easily get this ID.
.pop() takes the last item off of an array and returns it.
cy.url().then((url) => {
const splitUrl = url.split('/');
const ending = splitUrl.pop();
const id = ending.split('?')[0];
// code using id
})
I've been overly verbose in laying out each line, but you could theoretically combine it into one line as:
const id = url.split('/').pop().split('?')[0];
We could even simplify this a little bit, by using cy.location('pathname').
// assuming url is something like http://localhost:1234/survey/20?vbpCategoryId
cy.location('pathname').then((pathname) => {
/**
* `pathname` yields us just the path, excluding the query parameters and baseUrl
* (in this case, `?vbpCategoryId` and `http://localhost:1234`),
* so we would have a string of `/survey/20`.
*/
const id = pathname.split('/').pop();
});
Or you can use the .replace method with a regex to extract just the number from your url and then save it like this:
cy.url().then((URL) => {
const id = +URL.replace(/[^0-9]/g, '') //Gets the id 20 and changes it to a number
cy.wrap(id).as('urlId')
})
cy.get('#urlId').then((id) => {
//access id here
})
In case you don't want the id to be converted into a number you can simply remove the + from URL.replace like this:
cy.url().then((URL) => {
const id = URL.replace(/[^0-9]/g, '') //Gets the id 20
cy.wrap(id).as('urlId')
})
cy.get('#urlId').then((id) => {
//access id here
})

JS React: replacing regex with component in a string

Given a string with the format:
'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.'
I'd like to split it using a RegEx and replace the coincidences with some React components. The string would have the type of component (FaIcon) and a props in it such as the name of the icon (Upload).
The objective with this is to be able to use React components within translated strings, and the expected return value would be something like:
[
'This is a string with some ',
<FaIcon iconName="Upload" />,
' in it as ',
<FaIcon iconName="Download" />,
' these two.'
]
The method
Currently, I've got a method which returns either a string or an array. This is compatible with React render methods, since if we return an array it will be capable of rendering any components on that array.
As I'll use it to translate some strings, I've created this custom hook:
const useCustomTranslation = () => {
const { t } = useTranslation();
const tlt = (...args) => {
// const str = t(...args);
const testStr =
'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.';
const reg = /(?<=::FaIcon)(.*?)(?=::)/g;
const preStrAr = testStr.split(reg);
console.log(preStrAr);
};
return { tlt };
};
The problem
Currently, this method is logging this:
[
"This is a string with some ::FaIcon",
"Upload",
":: icons in it as ::FaIcon",
"Download",
":: these two."
]
As you can see, it's not including the ::FaIcon and the final ::, as I haven't been able to find the right Regex to do so. But even if I got to that point, I feel like then I should have to re-iterate through the array to replace the strings with the right component, again using Regex to see if the array item matches the right format.
I find this somehow overcomplicated, and I think there has to be a much cleaner and easy way to get it (correct me if maybe I'm wrong and this is the only way).
Is there any way where I can split a string using a Regex, using part of the matched group to replace the string by another content using that matched string?
Perhaps you meant to do this?
/::FaIcon(.*?)::/ without the look
const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/::FaIcon(.*?)::/g,function(_,match) {
return `<FaIcon iconName="${match}" />`
})
console.log(newText)
To make an array you can do
const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/\s?::FaIcon(.*?)::\s?/g,function(_,match) {
return `::<FaIcon iconName="${match}" />::`
}).split("::")
console.log(newText)
Finally, I've made it using (sadly) the re-iteration method, as it's the only way I can see it would work. Thanks to #mplungjan for his first answer, which gave me the hints to get it working:
export const replaceIconInStr = (str) => {
// Matches the whole icon component pattern
const regComponent = /(::FaIcon.*?::)/g;
// Matches just the component prop we need
const regIconName = /::FaIcon(.*?)::/g;
// Split the string by the component pattern
const splittedStr = str.split(regComponent);
// If there are any matches
if (splittedStr.length) {
// Match the elements in the array and get the prop to replace it by the real component
return splittedStr.map((el) => {
const matched = regIconName.exec(el)?.[1];
if (matched) {
return <FaIcon iconName={matched} />;
}
return el;
});
}
// If there is no pattern matching, return the original string
return str;
};

Regex using array.filter in javascript

I'm trying to use a regular expression to filter the name column in a csv file that has be put into an object array. Everything works fine if I type the exact value.
values I want "king" to match are below:
kingkong, king kong, king-kong, king_kong, king11, kongking, kong-king, kong_king, kong king, 11king
I've tried using filter and find methods but I want to use filter to return multiple values if they exist. I have tried the following regex but can't figure out the proper sytax if it is even correct.
const CSVToJSON = require('csvtojson');
const user = "king";
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter(function(v, i){
return ((v["name"]== /\bking.*/g));
})
You can use the following approach.
const CSVToJSON = require('csvtojson');
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter(function(v, i){
return ((v["name"].match(/king/g)));
});
return statement could be something like
return ((/king/g).test(v["name"]));
OR
return ((v["name"].match(/king/g)));
Both should work
However, your sample patterns show that king might stand either at the beginning or at the end of the target (bot can't have both prefix and suffix). If I am right, that means you don't need regex for that.
const CSVToJSON = require('csvtojson');
const user = "king";
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter((v, i) => v.startsWith(user) || v.endsWith(user))
/*rest of the code */
});
If king can stand anywhere, you can simply use includes instead.
This is what worked, I'm totally new to JavaScript:
const user = args;
var regex = new RegExp(user, "g");
CSVToJSON().fromFile("./locations.csv").then(source => {
var found = source.filter(function(v, i){
return ((v["name"].match(regex)));
})

How to filter data with an array of strings matching at least one?

I'm quite new to ReactJS and work on a simple application which shows many different data (called apps). I want to implement a live free text search-filter. For that I'm using an Input Element, calling a JavaScript function if the value is changing. It's working quite good. But only for one string. If I want to filter for more words it's handled as an "AND" filter. But I want an "OR" filter.
I have the apps and filter them with a searchString. The User has to input at least three characters. If the user enters two words with three characters f.e. 'app' and 'red', I want to filter for the elements which has the words 'app' OR 'red' in the title. If min. one of the filter-strings matches, the app is shown. That's the plan.
I tried with .indexOf(), .includes() and nothing matches, even in the documentation I found nothing like an "OR" filter-search.
Here is my code, working for one string:
updateSearch(event) {
let searchString = event.target.value.toLowerCase()
let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } ); //Only words with at least 3 chars are allowed in the array
if (searchString.length >= 3) { //Check if the minimun amount of characters is fullfilled
let allApps = this.props.applications;
let apps = allApps.filter(app =>
app.title.toLowerCase().includes(searchString)
);
this.props.updateApplications(apps);
} else {
this.clearSearch()
}
}
my Input element:
<Input
id="freeTextSearch"
className="searchInput"
onChange={this.updateSearch.bind(this)}
autoComplete="off"
action={
<Button
id="freeTextSearchButton"
name="search"
icon="search"
onClick={() => this.clearSearch()}
/>
}
placeholder="Search"
/>
Thanks for the help
Yvonne
ANSWER:
Thank you 'Silvio Biasiol'. Your Solution gave me the right hint. Now I have an 'OR' filter-search matching at least one word. The function now looks like:
updateSearch(event) {
let searchString = event.target.value.toLowerCase()
let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } )
if (searchStringSplit.length >=1) { //Check if there is at least on word with tree letters
let allApps = this.props.applications
// If at least a word is matched return it!
let apps = allApps.filter(app => {
let containsAtLeastOneWord = false
searchStringSplit.forEach(searchWord => {
if (app.title.toLowerCase().includes(searchWord))
containsAtLeastOneWord = true;
})
if (containsAtLeastOneWord)
return app
}
);
this.props.updateApplications(apps)
} else { // user deletes manually every word
this.clearSearch()
}
}
Thanks at everyone
If you just want to match at least one word than it's pretty easy :)
let string = "My cool string"
let possibleStrings = [
'My cool string',
'My super cool string',
'Another',
'I am lon but sadly empty',
'Bruce Willis is better than Pokemon',
'Another but with the word string in it',
'Such string much wow cool']
// Split spaces
let searchString = string.toLowerCase().split(' ')
// Log the result, just wrap it in your react script
console.log(possibleStrings.filter(string => {
let containsAtLeastOneWord = false;
// If at least a word is matched return it!
searchString.forEach(word => {
if (string.toLowerCase().includes(word))
containsAtLeastOneWord = true;
})
if (containsAtLeastOneWord)
return string
}))
You are not using your searchStringSplit array. Using this array you could do the following:
const searchRegex = new RegExp(searchStringSplit.join("|"))
let apps = allApps.filter(app =>
searchRegex.test(app.title.toLowerCase())
);
You join your searchStringSplit array into a regex with the form term1|term2|term3... and match it aginst the title.
Another option would be to use the Array.prototype.some() function like this:
let apps = allApps.filter(app =>
searchStringSplit.some(searchString => app.title.toLowerCase().includes(searchString))
);
You fitler all your apps and for each app you check if it's title includes 'some' of the search strings.
trying to understand your code, suppose that searchString is "facebook twitter youtube"
let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } );
//searchStringSplit is like [ "facebook", "twitter", "youtube" ]
//allApps is like ["TWITTER","INSTAGRAM"]
allApps.filter(app=> searchStringSplit.includes(app.toLowerCase()))
//returning me all apps in allApps that are includes in searchStringSplit
// so return ["TWITTER"]
not sure if it's exactly what you need...if it's not please let me know so I can change the answer...

Check location path/search/hash for matching value

I have an array of strings like so: ['foo', 'bar', 'foo/*/test'] and a random URL like this: http://www.example.com/foo/bar?test=123/another=one#test.
The URL may or may not contain a query or a hash prop.
Is there a regex or simple functionality to check the URL, in the URL contains any of those values in the array?
I am aware of the String.prototype.includes function so we could just do:
let path = location.pathname and then path.includes('foo'), but I want strings that contain the structure of foo/*/bar/ to be of higher importance.
For example if the URL is like this: http://www.example.com/foo/1234/test, the function should only return for the value foo/*/test instead of directly return with the foo value inside of the array.
So as soon as I have a string inside of the array which contains a / or something, I want this value to check first or give this the top prio so to speak.
Thanks!
Since the formatting inside a reply is all messed up, I have to post it like this:
#VincentDecaux totally understand.My first thoughts would have been sth like this:
function checkUrl(url, arr) {
const checkForPaths = arr.filter(val => val.match(/[\/](\w+)/ig));
if (checkForPaths.length) {
return true;
}
const filteredArray = arr.filter(val => url.includes(val));
if (filteredArray.length) {
return true;
}
return false;
}
This might already work since I only want the function to return true/false in order to display sth. on the page depemding on this.

Categories

Resources