Home > database >  Modify array to make it usable with RegExp
Modify array to make it usable with RegExp

Time:12-04

I have an input array which contains various domains:

var sites = ["site2.com", "site2.com", "site3.com"];

I need to check, whether certain string domainName matches one of these sites. I used indexOf which worked fine, however problem occured when certain domainName was shown with subpage, e.g. subpage.site1.com. I tried to use some method with RegExp testing instead:

if(sites.some(function(rx) { return rx.test(domainName); })

however the first problem was that I needed to change "" for every element to "\\" to make it work with RegExp:

var sites = [/site1.com/, /site2.com/, /site3.com/];

while I want to keep array with quotation marks for end-user.

Second problem was that it returns true for in cases where compared domainName is not in array, but partially its name contains is part of element in array, for example anothersite1.com with site1.com. It's rare case but happens.

I can modify my input array with RegExp will start and end with ^$ escape characters, but it will complicate it even more, especially that I will need to also add ([a-z0-9] [.]) to match subpages.

I tried to use replace to change "foo" to \foo\, but I was unable since quation marks defines array elements. Also I tried to use replace with concat to merge string with escape characters to achieve element looking like RegExp formula from site1.com to ^([a-z0-9] [.])*site1\.com$ but got issues with escaping characters.

Is there a simpler way to achieve this goal?

CodePudding user response:

Use the String.prototype.includes() method to check if a string is included in another string.

var domainName = "subpage.site1.com";
var sites = ["site1.com", "site2.com", "site3.com"];

// Check if any of the sites are included in the domain name
var isMatch = sites.some(site => domainName.includes(site));

This will return true if domainName includes any of the sites in the sites array.

Alternatively, you could use the String.prototype.indexOf() method, which will return the index of the first occurrence of the specified string within the string.

var domainName = "subpage.site1.com";
var sites = ["site1.com", "site2.com", "site3.com"];

// Check if any of the sites are included in the domain name
var isMatch = sites.some(site => domainName.indexOf(site) !== -1);

This will return true if domainName includes any of the sites in the sites array. Note that this method does not support regular expressions, so you will not be able to use it to match subdomains as in your example.

You could also use the Array.prototype.filter() method to create a new array containing only the matching sites, and then check the length of that array to see if any matches were found.

var domainName = "subpage.site1.com";
var sites = ["site1.com", "site2.com", "site3.com"];

// Create a new array containing only the sites that are included in the domain name
var matchingSites = sites.filter(site => domainName.includes(site));

// Check if any matches were found
var isMatch = matchingSites.length > 0;

This will return true if domainName includes any of the sites in the sites array.

Overall, the includes() or indexOf() methods are probably the simplest ways to check if a string is included in another string.

CodePudding user response:

You can use the String.prototype.match method and pass in a regular expression to check if the domain name matches any of the sites in your array.

Here's an example:

var sites = ["site1.com", "site2.com", "site3.com"];
var domainName = "subpage.site1.com";

var regex = new RegExp(`^([a-z0-9] [.])*${domainName}$`);
var matches = sites.filter(site => site.match(regex));

console.log(matches); // ["site1.com"]

In the code above, we create a regular expression that matches the domainName with any subpage prefixes. We then use the Array.prototype.filter method to find any elements in the sites array that match the regular expression. This will return an array of matching elements, or an empty array if no matches were found.

Note that you can also use the Array.prototype.some method to check if any element in the sites array matches the regular expression, like this:

var matches = sites.some(site => site.match(regex));
console.log(matches); // true

This will return true if at least one element in the sites array matches the regular expression, and false otherwise.

CodePudding user response:

I don't think regex is needed here. You could temporarily prefix both the domainName and the site with a dot, and then call endsWith:

const sites = ["site1.com", "site2.com", "site3.com"];

const isValid = domainName => 
    sites.some(site => ("."   domainName).endsWith("."   site));

// demo
console.log(isValid("site1.com")); // true
console.log(isValid("subpage.site1.com")); // true
console.log(isValid("othersite1.com")); // false

CodePudding user response:

You can build a regex from the sites array and do a single regex test:

const sites = ["site1.com", "site2.com", "site3.com"];
const sitesRegex = new RegExp(
  '\\b('  
  sites.map(site => site.replace(/([\\\.(){}])/g, '\\$1')).join('|')  
  ')$'
);
console.log('sitesRegex: '   sitesRegex);
// tests:
['foo.com', 'notsite1.com', 'site1.com', 'www.site1.com'].forEach(site => {
  console.log(site   ' => '   sitesRegex.test(site));
});

Output:

sitesRegex: /\b(site1\.com|site2\.com|site3\.com)$/
foo.com => false
notsite1.com => false
site1.com => true
www.site1.com => true

Explanation of .replace() regex:

  • ( -- capture group 1 start
  • [\\\.(){}] -- character class with regex chars that need to be escaped
  • ) -- capture group 1 end
  • g flag -- global (match multiple times)

Explanation of resulting /\b(site1\.com|site2\.com|site3\.com)$/ regex:

  • \b -- word boundary
  • ( -- group start
  • site1\.com|site2\.com|site3\.com -- logically ORed and escaped sites
  • ) -- group end
  • $ -- anchor at end of string
  • Related