Regular Expression for any number divisible by 60 using C# .Net?

前端 未结 6 1403
梦谈多话
梦谈多话 2021-01-18 10:32

I need to apply validation on input time intervals that are taken in as seconds. Now i am not really good at Regular expressions. So can any body help making a regular expre

6条回答
  •  暖寄归人
    2021-01-18 11:05

    Note: Regular expressions are not the right tool for this. This is just for fun and to see how it could be done.

    Here is a regular expression that tests if a number is divisible by 60:

    ^0$|^(?!0)(?=.*[02468]0$)(?:[0369]|[147](?:[0369]*[147][0369]*[258])*(?:[0369]*[258]|[0369]*[147][0369]*[147])|[258](?:[0369]*[258][0369]*[147])*(?:[0369]*[147]|[0369]*[258][0369]*[258]))*0$

    It works by testing if the number is divisible by 3 and using a lookahead to check if it is divisble by 20. It differs from the regular expression posted by tiftik in the following ways:

    • It is slightly shorter.
    • It uses non-capturing groups.
    • Many languages (for example Javascript )don't support variable length lookbehind assertions. This regular expression does not use lookbehinds so it can for example also be used for client-side validation in a web application.
    • It disallows numbers with leading zeros (if you want to allow leading zeros just remove the (?!0)).

    This is the code I used to generate and test it:

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    
    class Program
    {
        Regex createRegex()
        {
            string a = "[0369]*";
            string b = "a[147]";
            string c = "a[258]";
            string r = "^0$|^(?!0)(?=.*[02468]0$)(?:[0369]|[147](?:bc)*(?:c|bb)|[258](?:cb)*(?:b|cc))*0$";
            r = r.Replace("b", b).Replace("c", c).Replace("a", a);
            return new Regex(r);
        }
    
        bool isDivisibleBy3(string s)
        {
            int sumOfDigits = 0;
            foreach (char c in s)
            {
                sumOfDigits += c - '0';
            }
            return sumOfDigits % 3 == 0;
        }
    
        bool isDivisibleBy20(string s)
        {
            return Regex.IsMatch(s, "^0$|[02468]0$");
        }
    
        bool isDivisibleBy60(string s)
        {
            return isDivisibleBy3(s) && isDivisibleBy20(s);
        }
    
        bool isValid(string s)
        {
            return Regex.IsMatch(s, "^0$|^[1-9][0-9]*$");
        }
    
        void Run()
        {
            Regex regex = createRegex();
            Console.WriteLine(regex);
    
            // Test on some random strings.
            Random random = new Random();
            for (int i = 0; i < 100000; ++i)
            {
                int length = random.Next(50);
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < length; ++j)
                {
                    sb.Append(random.Next(10));
                }
                string s = sb.ToString();
                bool isMatch = regex.IsMatch(s);
                bool expected = isValid(s) && isDivisibleBy60(s);
                if (isMatch != expected)
                {
                    Console.WriteLine("Failed for " + s);
                }
            }
        }
    
        static void Main()
        {
            new Program().Run();
        }
    }
    

提交回复
热议问题