简体   繁体   English

使用C#.Net可以被60整除的任何数字的正则表达式?

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

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 expression that can test whether a number is divisible by 60. 所以任何身体都可以帮助制作一个正则表达式,可以测试一个数字是否可被60整除。

I was wondering if i could use to test one that check that the number is divisible by 10 and then check whether the same is divisible by 6. 我想知道我是否可以用来测试一个检查数字是否可以被10整除,然后检查它是否可以被6整除。

For number divisible by 10 here [\\d*0] is the expression i guess. 对于可被10整除的数字,这里[\\ d * 0]是我猜的表达式。 Please correct me if i am wrong. 如果我错了,请纠正我。

Hope somebody solves my problem. 希望有人能解决我的问题。

Thanks 谢谢

Why not do N % 60 ? 为什么不做N % 60

Why you want to use regex for a job which can easily be done using one operator ? 为什么要将regex用于可以使用一个运算符轻松完成的工作?

As others have mentioned, regular expressions are completely the wrong tool to use for this. 正如其他人所提到的,正则表达式完全是错误的工具 Rather, use TryParse to convert the string to an integer, and then test whether the integer is divisible by 60. 相反,使用TryParse将字符串转换为整数,然后测试整数是否可被60整除。

That said, it is instructive to see how this could possibly work with a regexp. 也就是说,看看这有可能与正则表达式一起工作是有益的。

First off, of the one-digit numbers, only 0 is evenly divisible by 60. Of the non-one-digit numbers, all numbers divisible by 60 are also divisible by 20, and therefore end in 00, 20, 40, 60 or 80. That is easily tested with a regexp. 首先,在一位数的数字中,只有0可被60整除。在非一位数字中,所有可被60整除的数字也可被20整除,因此以00,20,40,60或80.使用正则表达式很容易测试。

Suppose it passes the first test. 假设它通过了第一次测试。 We know from this test that the number is divisible by 20. Now all we need to do is show that it is divisible by 3. If it is, then it is divisible by both 20 and 3 and therefore must be divisible by 60, since 20 and 3 are coprime. 我们从这个测试中知道这个数字可以被20整除。现在我们需要做的就是表明它可以被3整除。如果是,那么它可以被20和3整除,因此必须可被60整除,因为20和3是互质的。

So we need a regular expression that can determine if a number is divisible by 3. 所以我们需要一个正则表达式来确定一个数字是否可以被3整除。

It is well known that numbers divisible by three are such that the sum of their digits is divisible by 3. 众所周知,可被3整除的数字使得它们的数字之和可被3整除。

It is also well known that every regular expression corresponds to a finite state machine, and every finite state machine corresponds to a regular expression. 众所周知,每个正则表达式对应于有限状态机,并且每个有限状态机对应于正则表达式。

Therefore if we can come up with a finite state machine that determines divisibility by three, we're done. 因此,如果我们能够提出一个有限状态机来确定三个可分性,我们就完成了。

This is easily done. 这很容易做到。 Our finite state machine has three states, A, B and C. The start state is A. The accepting state is A. The transitions are: 我们的有限状态机有三种状态,A,B和C.开始状态是A.接受状态是A.转换是:

When in state A, inputs 0, 3, 6 and 9 go to state A. Inputs 1, 4 and 7 go to state B. Inputs 2, 5 and 8 go to state C. 当处于状态A时,输入0,3,6和9进入状态A.输入1,4和7进入状态B.输入2,5和8进入状态C.

When in state B, inputs 0, 3, 6 and 9 go to state B. Inputs 1, 4 and 7 go to state C. Inputs 2, 5 and 8 go to state A. 当处于状态B时,输入0,3,6和9进入状态B.输入1,4和7进入状态C.输入2,5和8进入状态A.

When in state C, inputs 0, 3, 6 and 9 go to state C. Inputs 1, 4 and 7 go to state A. Inputs 2, 5 and 8 go to state B. 当处于状态C时,输入0,3,6和9进入状态C.输入1,4和7进入状态A.输入2,5和8进入状态B.

All other inputs go to an error state. 所有其他输入都进入错误状态。

And we're done; 我们已经完成了; we have a finite state machine that checks for divisibility by 3. Therefore we can build a regexp that checks for divisibility by 3; 我们有一个有限的状态机,它检查可分性为3.因此我们可以构建一个regexp来检查3的可分性; if we combine that with the regexp that checks for divisibility by 20, then we have the desired regular expression. 如果我们将检查可消除性的正则表达式与20结合起来,那么我们就有了所需的正则表达式。 The language of numbers written in decimal notation divisible by 60 is a regular language. 以十进制表示法编写的数字语言可被60整除,是一种常规语言。

The actual construction of such a regular expression is left as an exercise. 这种正则表达式的实际构造留作练习。 (Looks like that's what tiftik has done.) (看起来这就是tiftik所做的。)

Exercise: can you come up with a regular expression that determines if string contains a decimal number that is evenly divisible by 70? 练习:你能想出一个正则表达式来判断字符串是否包含一个可被70整除的十进制数吗? If you can, let's see it. 如果可以,让我们看看。 If not, can you provide a proof that no such regular expression exists? 如果没有,你能否提供不存在这种正则表达式的证据? (That is, that the language I am describing is not regular.) (也就是说,我所描述的语言不规律。)

I've come up with this: 我想出来了:

^((?=[^147]*(([147][^147]*){3})*$)(?=[^258]*(([258][^258]*){3})*$)|(?=[^147]*(([147][^147]*){3})*[147][^147]*$)(?=[^258]*(([258][^258]*){3})*[258][^258]*$)|(?=[^147]*(([147][^147]*){3})*([147][^147]*){2}$)(?=[^258]*(([258][^258]*){3})*([258][^258]*){2}$))\\d*0(?<=[02468][048]|[13579][26]|^0)$

Note: I didn't use non-capturing groups for the sake of simplicity. 注意:为简单起见,我没有使用非捕获组。

Edit: Shorter version: 编辑:更短的版本:

^(?=[^147]*(?:(?:[147][^147]*){3})*(?:()|([147][^147]*)|((?:[147][^147]*){2}))$)(?=[^258]*(?:(?:[258][^258]*){3})*(?:()|([258][^258]*)|((?:[258][^258]*){2}))$)((?(1)(?(4)|.$)|.$)|(?(2)(?(5)|.$)|.$)|(?(3)(?(6)|.$)|.$))\\w*0(?<=[02468]0|^0)$

(+,/,-,*) in Regex are not used as mathematical operators. 正则表达式中的(+,/, - ,*)不用作数学运算符。 Use JavaScript instead. 请改用JavaScript。

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: 这是一个正则表达式,用于测试数字是否可被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: 它的工作原理是测试数字是否可被3整除,并使用前瞻来检查它是否可以除以20.它与tiftik在以下方面发布正则表达式不同:

  • It is slightly shorter. 它略短。
  • It uses non-capturing groups. 它使用非捕获组。
  • Many languages (for example Javascript )don't support variable length lookbehind assertions. 许多语言(例如Javascript)不支持可变长度的lookbehind断言。 This regular expression does not use lookbehinds so it can for example also be used for client-side validation in a web application. 此正则表达式不使用lookbehinds,因此它也可以用于Web应用程序中的客户端验证。
  • It disallows numbers with leading zeros (if you want to allow leading zeros just remove the (?!0) ). 它不允许带前导零的数字(如果你想允许前导零只删除(?!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();
    }
}

Regular expressions are the wrong tool for this job. 正则表达式是这项工作的错误工具。 Instead, try dividing by 60 and see if there is no remainder: 相反,尝试除以60,看看是否没有余数:

if (value % 60 == 0) {
  // is divisible by 60
  // ... do something ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM