正则表达式匹配 4 个组中的 2 个

Posted

技术标签:

【中文标题】正则表达式匹配 4 个组中的 2 个【英文标题】:Regex match 2 out of 4 groups 【发布时间】:2013-12-18 20:56:48 【问题描述】:

我想要一个正则表达式来匹配 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\t1\t", "Single", "C# Hack");
        Console.WriteLine("");
        foreach (var testCase in testCases)
        
            Console.WriteLine("0\t2\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

【问题讨论】:

也许您能描述一下您想要达到的结果?你想匹配什么?你会得到什么结果? 我添加了一些示例。或者,可以使用提供的示例代码来查看结果。 【参考方案1】:

对于 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]

由于所有交替都包含至少两个来自两个不同字符类别的字符,因此您一定会得到您希望的结果。

【讨论】:

这适用于 .Net 和 JavaScript,谢谢。你能解释一下不同类代表什么的逻辑吗?我想以此作为学习经验。【参考方案2】:

您可以使用所有格量词(使用原子组模拟),如下所示:

((?>[a-z]+)|(?>[A-Z]+)|(?>[^a-zA-Z]+))2,

由于使用所有格匹配可以防止回溯,例如,您不会遇到两个连续的小写字母组。所以完整的正则表达式是这样的:

^(?=.*((?>[a-z]+)|(?>[A-Z]+)|(?>[^a-zA-Z]+))2,).8,$

不过,如果是我的话,我会削减前瞻,只使用表达式((?>[a-z]+)|(?>[A-Z]+)|(?>[^a-zA-Z]+))2,,并单独检查长度。

【讨论】:

我需要添加一些转义字符吗? .NET 给了我这个错误:parsing "^(?=.*([a-z]++|[A-Z]++|[^a-zA-Z]++)2,).8,$" - Nested quantifier +. @EugeneS.: .net 没有所有格量词功能。但是,您可以用原子组替换所有格量词:[A-Z]++ -> (?>[A-Z]+) 对,C# 不支持所有格量​​词,抱歉。你可以Emulate them with atomic groups,我已经编辑了我的答案来反映这一点。 适用于 .NET。看起来我在 JavaScript 中使用它很不走运,因为它不支持原子组。

以上是关于正则表达式匹配 4 个组中的 2 个的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式中 如何取出所有组中的值?

用于检查 4 个不同字符组中的至少 3 个的正则表达式

Perl 中的正则表达式组:如何从正则表达式组中捕获与字符串中出现的未知数量/多个/变量匹配的元素到数组中?

爬虫必备正则re模块

Python:在元组中存储许多正则表达式匹配?

正则表达式