如何将字符串与Javascript中的模式数组匹配?
Posted
技术标签:
【中文标题】如何将字符串与Javascript中的模式数组匹配?【英文标题】:How to match a string against an array of pattern in Javascript? 【发布时间】:2015-06-10 14:12:12 【问题描述】:我有两个变量:
var input = "user1@gmail.com";
var preferredPatterns = ["*@gmail.com", "*@yahoo.com", "*@live.com"];
想要将输入与首选模式数组匹配。如果任何模式匹配我必须做某些任务(在这个例子中,输入是一个明确的匹配)。如何匹配 javascript 中的模式数组?
【问题讨论】:
那些是什么模式?这些不是正则表达式。 我怎样才能把它们变成? 你需要把每一个都拿走并重写。你知道正则表达式语法吗? 更不用说,user1@gmail.com
也不是字符串。
【参考方案1】:
您可以将您的模式(如果它们是有效的正则表达式)编译成一个以提高性能:
var masterPattern = new RegExp(patterns.join('|'));
把它们放在一起:
var input = 'user1@gmail.com';
var preferredPatterns = [
".*@gmail.com$",
".*@yahoo.com$",
".*@live.com$"
];
var masterPattern = new RegExp(preferredPatterns.join('|'));
console.log(masterPattern.test(input));
// true
【讨论】:
这不是问题的一部分。如果你愿意,最好使用@AvinashRaj 的解决方案。根据您的原始问题,这只会非常非常快地找到任何模式是否匹配。 (手工制作masterPattern
会更快,因为您可以重构.* -- $
位以获得更快的速度)。
但是这个显示SyntaxError: Invalid regular expression: /*@qa-server5.com$|*@qa-server4.com$/
“如果它们是有效的正则表达式”。你的不是 - *
前面需要一个句点。如果您想允许您的用户输入模式,那么您还需要一种将它们转换为有效正则表达式的方法(转义任何危险字符,并将*
转换为.*
,首先)。否则,只需首先编写正确的正则表达式模式。【参考方案2】:
您需要在将变量作为正则表达式传递时使用RegExp
构造函数。
var input = 'user1@gmail.com';
var preferredPatterns = [".*@gmail\\.com$", ".*@yahoo\\.com$", ".*@live\\.com$"];
for (i=0; i < preferredPatterns.length;i++)
if(input.match(RegExp(preferredPatterns[i])))
console.log(preferredPatterns[i])
点是正则表达式中的一个特殊元字符,可以匹配任何字符。您需要转义正则表达式中的点以匹配文字点。
正如@zerkms 所说,您也可以使用以下模式列表。
var preferredPatterns = ["@gmail\\.com$", "@yahoo\\.com$", "@live\\.com$"];
【讨论】:
你的意思是我需要给出一个精确的模式来匹配电子邮件 ID? 不,我的意思是你可以从正则表达式中删除.*
,什么都不会改变。
它给出:SyntaxError: Invalid regular expression: /*@qa-server5.com$/
在您的正则表达式中在星号前使用点。请重新检查我使用的正则表达式。
.* 将匹配包括空格在内的所有字符。所以我们应该使用非空格字符 \S 即 ["\\S*@gmail\\.com", "\\S*@yahoo\\.com", "\\S*@live\\.com"] 【参考方案3】:
试试这个辅助函数:
/**
* Returns an integer representing the number of items in the patterns
* array that contain the target string text
*/
function check(str, patterns)
return patterns.reduce(function (previous, current)
return previous + (str.indexOf(current) == -1 ? 0 : 1);
, 0);
check("user@gmail.com", ["@gmail.com", "@yahoo.com", "@live.com"]; // returns 1
check("user@live.com", ["@gmail.com", "@yahoo.com", "@live.com"]; // returns 0
【讨论】:
【参考方案4】:如果您想要一种通用方法来匹配正则表达式列表,那么 Avinash Raj 的答案的某个版本将起作用。
基于您指定特定域的事实,您可能希望匹配any valid email address using the regex here,如果匹配,则检查该域是否是首选域。当然,有许多不同的方法可以做到这一点。这里只是一个简单的例子,在@
上拆分并使用jQuery.inArray()
来检查该域是否是首选。
var preferredDomains = ["gmail.com", "yahoo.com", "live.com"];
function isValid(inputVal)
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]0,66)\.([a-z]2,6(?:\.[a-z]2)?)$/i;
return re.test(inputVal) && $.inArray(inputVal.split('@')[1], preferredDomains) > -1;
这里的优点是底层的正则表达式不会改变,只是更容易阅读/维护域列表。您可以调整它以捕获组中的域,而不是使用 split()。
【讨论】:
【参考方案5】:没有正则表达式你可以做如下;
function matchPattern(xs, [y,...ys])
function helper([x,...xs])
return "*" + xs.join('') === y ? true
: xs.length ? helper(xs)
: false;
return helper(xs) ? y
: ys.length ? matchPattern(xs,ys)
: "No Match..!";
var input = "user1@gmail.com",
preferredPatterns = ["*@yahoo.com", "*@live.com", "*@gmail.com"];
result = matchPattern(input, preferredPatterns);
console.log(result);
【讨论】:
【参考方案6】:preferredPatterns.forEach(function(element, index)
if(input.match('/'+element) != null)
console.log('matching ' + element)
)
如果字符串匹配任何模式,您可以编写自定义逻辑。
【讨论】:
【参考方案7】:您可以遍历数组,然后使用正则表达式与单个项目进行比较。
【讨论】:
以上是关于如何将字符串与Javascript中的模式数组匹配?的主要内容,如果未能解决你的问题,请参考以下文章