簡體   English   中英

正則表達式匹配4組中的2組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM