I have implemented the search feature using JavaScript and Regex. Firstly, I converted the input string into tokens then searched for it in the target array.
This is the sample code.
const tokens = inputString
.toLowerCase()
.split(' ')
.filter(function (token) {
return token.trim() !== ''
})
const searchTermRegex = new RegExp(tokens.join(' '), 'gim')
const filteredList = targetArray.filter(function (item) {
return item.match(searchTermRegex)
})
This code is running fine, only problem is it does not search if the words are present in random order.
For example, if target string is "scrape the data from pages", and I search for "data scrape" then it is not able to detect it.
What's the better solution for it?
Expected Output: If at least a single word from the input is present in the target string, it should show that string in the final output.
Since it's not clear whether your need both the words in your targeted result or either of them, there is an answer for either case therefore I'm adding solution if both words are need for which you'll need positive lookaheads, and it seems like your requirement is that you need to have both word complete in your inputString, that's why I've added word boundaries in the regex using \b, if that's not needed you can update the token mapper with this:
(?=.*${token})
Also I've refactored your code a little bit, hope that helps
const tokens = inputString
.split(' ')
.filter(Boolean)
.map(token => `(?=.*\\b${token}\\b)`);
const searchTermRegex = new RegExp(tokens.join(''), 'gim');
const filteredList = targetArray.filter(item => item.match(searchTermRegex));
You could do like this. I think split not necessary
const inputString = "scrape the data from pages"
const targetArray = ["data", "scrape"]
const filteredList = targetArray.every(function(item) {
return inputString.indexOf(item) > -1
})
console.log("matchStatus", filteredList)
OR Regex
const inputString = "scrape the data from pages"
const targetArray = ["data", "scrape"]
const filteredList = new RegExp(targetArray.join('|'),'gim').test(inputString)
console.log("matchStatus", filteredList)
Related
I want to know about the algorithm for below question in JavaScript.
Check whether the given word can be "programming" or not by removing the substring between them. You can only remove one substring from the given the word.
Give answer in 'yes' and 'no'
example answer explanation
"progabcramming" yes remove substring 'abc'
"programmmeding" yes remove substring 'med'
"proasdgrammiedg" no u have to remove 2 subtring 'asd' and 'ied'
which is not allowed
"pxrogramming" yes remove substring 'x'
"pxrogramminyg" no u have to remove 2 subtring 'x' and 'y'
which is not allowed
Please tell me an algorithm to solve it
{
// will create a regexp for fuzzy search
const factory = (str) => new RegExp(str.split('').join('(.*?)'), 'i')
const re = factory('test') // re = /t(.*?)e(.*?)s(.*?)t/i
const matches = re.exec('te-abc-st') ?? [] // an array of captured groups
const result = matches
.slice(1) // first element is a full match, we don't need it
.filter(group => group.length) // we're also not interested in empty matches
// now result contains a list of captured groups
// in this particular example a single '-abc-'
}
I'm not sure how efficient this code is, but only thing i can come up with is using regular expression.
const word = 'programming';
const test = ['progabcramming', 'programmmeding', 'proasdgrammiedg', 'pxrogramming', 'pxrogramminyg', 'programming'];
// create regular expression manually
// const regexp = /^(p).+(rogramming)|(pr).+(ogramming)|(pro).+(gramming)|(prog).+(ramming)|(progr).+(amming)|(progra).+(mming)|(program).+(ming)|(programm).+(ing)|(programmi).+(ng)|(programmin).+(g)$/;
// create regular expression programmatically
let text = '/^';
word.split('').forEach((character, i) => {
text += i ? `(${word.substring(0, i)}).+(${word.substring(i)})|` : '';
});
text = text.substring(text.length - 1, 1) + '$/';
const regexp = new RegExp(text);
// content output
let content = '';
test.forEach(element => {
content += `${element}: ${regexp.test(element)}\n`;
});
document.body.innerText = content;
Given an array like the below code :
let words = ['bring','constant','bath','spring','splashing']
How do I print all string characters with ing characters from the words array ?
You need to use endsWith method to check if the word ends with a specific value.
let words = ['bring','constant','bath','spring','splashing']
const result = words.filter(w => w.endsWith('ing'))
result.forEach(w => console.log(w))
You also can use regular expressions with dollar sign $ means end with.
let words = ['bring','constant','bath','spring','splashing']
const result = words.filter(w => /(ing)$/.test(w))
result.forEach(w => console.log(w))
As author want to check if ing exist in the middle of the word or not. In that case you can just use normal regex with String.match() method without $ sign at end.
Live Demo :
let words = ['bring','constant','bath','spring','splashing', 'tingtong'];
const res = words.filter(word => word.match(/ing/ig));
console.log(res);
Or you can also achieve that by using .includes() method.
Live Demo :
let words = ['bring','constant','bath','spring','splashing', 'tingtong'];
const res = words.filter(word => word.includes('ing'));
console.log(res);
I have a string that is a normal sentence. I need to replace the characters in the string if they are found in a given array. For example,
const arr = ["(model: Audi)", "(model: Kia)"];
if the string is:
"How is your (model: Audi) today?";
The result should be "How is your Audi today?".
Is there a way to do this with regex? I read somewhere that regex has better performance. I've tried looping thru the array then replacing the characters but I couldnt get it working and my solution would have nested loops due to the given string
const arr = ["(model: Audi)", "(model: Kia)"];
let string = "How is your (model: Audi) today?";
for (let data of arr){
string = string.replace(data, data.split(": ")[1].replace(")",""))
}
console.log(string);
Well, this is the simplest I have managed to do.
However, I myself kind of consider it a bad solution.
Let me know if it helps at all...
const myString = "How is your (model: Audi) today?";
const arr = ["(model: Audi)", "(model: Kia)"];
arr.forEach(item => {
const part = item.match(/\w+\)$/)[0];
const subPart = part.substring(0, part.length - 1);
if (myString.includes(item))
console.log(myString.replace(item, subPart));
});
I have problem with regex and need some help.
Current I have url has type
/search/:year/:month/:day/xxxx with :month and :day maybe exist or not . Now I need replace /search/:year/:month/:day patern on my url with empty string. Meaning get remain of url part. So this is some example below
1.'/search/2017/02/03/category/gun' => '/category/gun'
2.'/search/2017/02/03/' => '/'
3.'/search/2017/01/category/gun' => '/category/gun/'
4.'/search/2017/category/gun/' => '/category/gun/'
5.'/search/2018/?category=gun&type%5B%5D=sendo' => '/?category=gun&type%5B%5D=sendo/'
I try to use regex = /^\/search\/((?:\d{4}))(?:\/((?:\d|1[012]|0[1-9])))?(?:\/((?:[0-3]\d)))/
But it is failed for case /search/2017/category/gun/
const regex = /^\/search\/((?:\d{4}))(?:\/((?:\d|1[012]|0[1-9])))?(?:\/((?:[0-3]\d)))/
const testLink = [
'/search/2017/02/03/category/gun/',
'/search/2017/01/category/gun/',
'/search/2017/category/gun/',
'/search/2017/02/03/category/gun/',
'/search/2018/?category=gun&type%5B%5D=sendo'
]
testLink.forEach((value, i) => {
console.log(value.replace(regex, ''))
console.log('-------------------')
})
Use this regex pattern (\/search\/.*\d+)(?=\/)
Demo
const regex = /(\/search\/.*\d+)(?=\/)/g;
const testLink = [
'/search/2017/02/03/category/gun/',
'/search/2017/01/category/gun/',
'/search/2017/',
'/search/2017/02/03/category/gun/',
'/search/2018/?category=gun&type%5B%5D=sendo'
]
testLink.forEach((value, i) => {
console.log(value.replace(regex, ''))
console.log('-------------------')
})
Splitting on the following pattern seems to work:
\d{4}(?:/\d{2})*
This would place the target you want as the second element in the split array, with the first portion being what precedes the year-digit portions of the path.
input = '/search/2017/02/03/category/gun';
parts = input.split(/\d{4}(?:\/\d{2})*/);
console.log(parts[1]);
console.log('/search/2017/02/03'.split(/\d{4}(?:\/\d{2})*/)[1]);
console.log('/search/2017/01/category/gun'.split(/\d{4}(?:\/\d{2})*/)[1]);
console.log('/search/2017/category/gun/'.split(/\d{4}(?:\/\d{2})*/)[1]);
Whether you do or do not expect a final trailing path separator is not entirely clear. In any case, the above answered can be modified per that expectation.
Here's one way:
strings = [
'/search/2017/02/03/category/gun',
'/search/2017/02/03/',
'/search/2017/01/category/gun',
'/search/2017/category/gun/',
]; for (var i = 0; i < strings.length; i++) {
alert(strings[i].replace(/\/search\/[0-9\/]+(\/)(category\/[^\/$]+)?.*/,'$1$2'));
}
you can use the same regex but revers the order of this part (?:\d|1[012]|0[1-9])
as following (?:\d|1[012]|0[1-9]) and make last group optional as following ((?:[0-3]\d)))?
const regex = /^\/search\/((?:\d{4}))(?:\/((?:0[1-9]|1[012]|\d)))?(?:\/((?:[0-3]\d)))?/
const testLink = [
'/search/2017/02/03/category/gun/',
'/search/2017/01/category/gun/',
'/search/2017/category/gun/',
'/search/2017/02/03/category/gun/'
]
output
/category/gun/
/category/gun/
/category/gun/
/category/gun/
if you are sure of date format so you can simplify your exp to be ^\/search\/\d{4}(?:\/\d{1,2}){0,2}
current regex to match multiple subnets delimited by a space rexp = /^([01]?\d\d?|2[0-4]\d|25[0-5])(?:\.[01]?\d\d?|2[0-4]\d|25[0-5]){3}(?:\/[0-2]\d|\/3[0-2])?$(\s(^([01]?\d\d?|2[0-4]\d|25[0-5])(?:\.[01]?\d\d?|2[0-4]\d|25[0-5]){3}(?:\/[0-2]\d|\/3[0-2])?$))*$/)
test string 192.168.2.1/24 192.168.2.1/32
Your regex seems to be broken. You can try this one:
^([01]?\d\d?|2[0-4]\d|25[0-5])(?:\.[01]?\d\d?|2[0-4]\d|25[0-5]){3}(?:\/[0-2]\d|\/3[0-2])?(\s+([01]?\d\d?|2[0-4]\d|25[0-5])(?:\.[01]?\d\d?|2[0-4]\d|25[0-5]){3}(?:\/[0-2]\d|\/3[0-2]))*$
Another option is to parse the string using Javascript and use a simpler regex for each piece. Here is an example:
const s = '192.168.2.1/24 192.168.2.1/32 250.161.23.1/32 0.1.2.1/01';
const pattern = /([01]?\d\d?|2[0-4]\d|25[0-5])(?:\.[01]?\d\d?|2[0-4]\d|25[0-5]){3}(?:\/[0-2]\d|\/3[0-2])/;
const result = s.trim().split(/\s+/).map(e => e.match(pattern) != null).reduce((result, next) => result && next, true);
console.log(result);
This prints:
true
Though you can certainly decompose the string using regex, it might be much easier using code like this:
subnetsString = "192.168.2.1/24 192.168.2.1/32";
subnets = subnetsString.split(" ");
firstSubnet = subnets[0];
ip = firstSubnet.split("/")[0];
console.log(ip); // output: 192.168.2.1