[英]Regex match 2 out of 4 groups
我希望单个Regex表达式匹配2组小写,大写,数字或特殊字符。 长度也需要大于7。
我目前有这个表达方式
^(?=.*[^a-zA-Z])(?=.*[a-z])(?=.*[A-Z]).{8,}$
但是,它强制字符串具有小写和大写以及数字或特殊字符。
我目前使用4个不同的正则表达式实现了这个,我用一些C#代码询问。
我计划在JavaScript中重用相同的表达式。
这是示例控制台应用程序,显示了两种方法之间的差异。
class Program
{
private static readonly Regex[] Regexs = new[] {
new Regex("[a-z]", RegexOptions.Compiled), //Lowercase Letter
new Regex("[A-Z]", RegexOptions.Compiled), // Uppercase Letter
new Regex(@"\d", RegexOptions.Compiled), // Numeric
new Regex(@"[^a-zA-Z\d\s:]", RegexOptions.Compiled) // Non AlphaNumeric
};
static void Main(string[] args)
{
Regex expression = new Regex(@"^(?=.*[^a-zA-Z])(?=.*[a-z])(?=.*[A-Z]).{8,}$", RegexOptions.ECMAScript & RegexOptions.Compiled);
string[] testCases = new[] { "P@ssword", "Password", "P2ssword", "xpo123", "xpo123!", "xpo123!123@@", "Myxpo123!123@@", "Something_Really_Complex123!#43@2*333" };
Console.WriteLine("{0}\t{1}\t", "Single", "C# Hack");
Console.WriteLine("");
foreach (var testCase in testCases)
{
Console.WriteLine("{0}\t{2}\t : {1}", expression.IsMatch(testCase), testCase,
(testCase.Length >= 8 && Regexs.Count(x => x.IsMatch(testCase)) >= 2));
}
Console.ReadKey();
}
}
Result Proper Test String
------- ------- ------------
True True : P@ssword
False True : Password
True True : P2ssword
False False : xpo123
False False : xpo123!
False True : xpo123!123@@
True True : Myxpo123!123@@
True True : Something_Really_Complex123!#43@2*333
对于javascript,您可以使用此模式查找不同字符类之间的边界:
^(?=.*(?:.\b.|(?i)(?:[a-z]\d|\d[a-z])|[a-z][A-Z]|[A-Z][a-z]))[^:\s]{8,}$
如果找到边界,你肯定有两个不同的类。
图案细节:
\b # is a zero width assertion, it's a boundary between a member of
# the \w class and an other character that is not from this class.
.\b. # represents the two characters with the word boundary.
字母和数字之间的边界:
(?i) # make the subpattern case insensitive
(?:
[a-z]\d # a letter and a digit
| # OR
\d[a-z] # a digit and a letter
)
大写和小写字母之间的边界:
[a-z][A-Z] | [A-Z][a-z]
由于所有替换都包含来自两个不同角色类的至少两个字符,因此您一定会获得您希望的结果。
您可以使用所有格量词(使用原子组模拟),如下所示:
((?>[a-z]+)|(?>[A-Z]+)|(?>[^a-zA-Z]+)){2,}
因为使用所有格匹配会阻止回溯,所以你不会遇到两组连续的小写字母组。 所以完整的正则表达式将是这样的:
^(?=.*((?>[a-z]+)|(?>[A-Z]+)|(?>[^a-zA-Z]+)){2,}).{8,}$
虽然,是我,我会削减前瞻,只需使用表达式((?>[az]+)|(?>[AZ]+)|(?>[^a-zA-Z]+)){2,}
,并分别检查长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.