Eri*_*ert 15
正如其他人所提到的,正则表达式完全是错误的工具.相反,使用TryParse将字符串转换为整数,然后测试整数是否可被60整除.
也就是说,看看这有可能与正则表达式一起工作是有益的.
首先,在一位数字中,只有0可被60整除.在非一位数字中,所有可被60整除的数字也可被20整除,因此以00,20,40,60或80.使用正则表达式很容易测试.
假设它通过了第一次测试.我们从这个测试中知道这个数字可以被20整除.现在我们需要做的就是表明它可以被3整除.如果是,那么它可以被20和3整除,因此必须可被60整除,因为20和3是互质的.
所以我们需要一个正则表达式来确定一个数字是否可以被3整除.
众所周知,可被3整除的数字使得它们的数字之和可被3整除.
众所周知,每个正则表达式对应于有限状态机,并且每个有限状态机对应于正则表达式.
因此,如果我们能够提出一个有限状态机来确定三个可分性,我们就完成了.
这很容易做到.我们的有限状态机有三种状态,A,B和C.开始状态是A.接受状态是A.转换是:
当处于状态A时,输入0,3,6和9进入状态A.输入1,4和7进入状态B.输入2,5和8进入状态C.
当处于状态B时,输入0,3,6和9进入状态B.输入1,4和7进入状态C.输入2,5和8进入状态A.
当处于状态C时,输入0,3,6和9进入状态C.输入1,4和7进入状态A.输入2,5和8进入状态B.
所有其他输入都进入错误状态.
我们已经完成了; 我们有一个有限的状态机,它检查可分性为3.因此我们可以构建一个regexp来检查3的可分性; 如果我们将检查可消除性的正则表达式与20结合起来,那么我们就有了所需的正则表达式. 以十进制表示法编写的数字语言可被60整除,是一种常规语言.
这种正则表达式的实际构造留作练习.(看起来这就是tiftik所做的.)
练习:你能想出一个正则表达式来判断字符串是否包含一个可被70整除的十进制数吗?如果可以,让我们看看.如果没有,你能否提供不存在这种正则表达式的证据?(也就是说,我所描述的语言不规律.)
我想出来了:
^((?=[^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)$
注意:为简单起见,我没有使用非捕获组.
编辑:更短的版本:
^(?=[^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)$