我可以使用正则表达式来搜索数字的倍数吗?

时间:2010-12-23 11:24:19

标签: regex

我正在尝试搜索一个大型项目,以查找我已声明数组的所有示例[48]作为大小或任何48的倍数。

我可以使用正则表达式函数来查找48 * n的匹配吗?

感谢。

6 个答案:

答案 0 :(得分:20)

在这里(使用PHP的PCRE语法):

^(0*|(1(01*?0)*?1|0)+?0{4})$

用法:

preg_match('/^(0*|(1(01*?0)*?1|0)+?0{4})$/', decbin($number));

现在,为什么它有效:

我们知道48真的只是3 * 16。 16只是2*2*2*2。因此,任何可被2 ^ 4整除的数字将在其二进制表示0中具有最多4位。因此,通过用0{4}$结束正则表达式相当于说该数字可被2^4整数(或{ {1}})。那么,左边的位需要被3整除。所以使用this answer的正则表达式,我们可以判断它们是否可以被3整除。所以如果整个正则表达式匹配,则数字可以被3整除。和16,因此48 ...

... QED

(注意,当16为0时,前导0|个案处理失败的匹配。我已经对从$number0的所有数字进行了测试,并且每次都正确匹配...

答案 1 :(得分:2)

您的问题的概括是询问 x 是否是表示基本 b n 的倍数的字符串。这与询问 x 除以 n 的余数是否为0相同。您可以轻松创建DFA来计算此值。

使用 n 状态创建DFA,编号从0到 n - 1.状态0是初始状态和唯一接受状态。每个状态都有 b 传出转换,一个用于字母表中的每个符号(因为base- b 为您提供 b 数字)。

每个状态代表我们到目前为止看到的 x 部分的剩余部分,除以 n。这就是为什么我们有 n 他们(将数字除以 n 得到的余数在0到 n - 1的范围内),以及为什么状态0是接受状态。

由于 x 的数字是从左到右处理的,如果我们从 x 的前几位数字中得到一个 y 的数字,读取数字 d ,我们从 yb + d获得 y 的新值。但更重要的是,其余 r 更改为( rb + d )mod n。所以我们现在知道如何连接过渡弧并完成DFA。

您可以为任何 n b 执行此操作。例如,在这里,可以接受基数为10的多个18(行上的状态,列上的输入):

   |  0  1  2  3  4  5  6  7  8  9
---+-------------------------------
→0 |  0  1  2  3  4  5  6  7  8  9  ←accept
 1 | 10 11 12 13 14 15 16 17  0  1
 2 |  2  3  4  5  6  7  8  9 10 11
 3 | 12 13 14 15 16 17  0  1  2  3
 4 |  4  5  6  7  8  9 10 11 12 13
 5 | 14 15 16 17  0  1  2  3  4  5
 6 |  6  7  8  9 10 11 12 13 14 15
 7 | 16 17  0  1  2  3  4  5  6  7
 8 |  8  9 10 11 12 13 14 15 16 17
 9 |  0  1  2  3  4  5  6  7  8  9
10 | 10 11 12 13 14 15 16 17  0  1
11 |  2  3  4  5  6  7  8  9 10 11
12 | 12 13 14 15 16 17  0  1  2  3
13 |  4  5  6  7  8  9 10 11 12 13
14 | 14 15 16 17  0  1  2  3  4  5
15 |  6  7  8  9 10 11 12 13 14 15
16 | 16 17  0  1  2  3  4  5  6  7
17 |  8  9 10 11 12 13 14 15 16 17

随着 n b 越来越大,这些变得非常繁琐,但你可以明显地编写一个程序来为你生成它们没问题。

答案 2 :(得分:1)

1|48|2304|110592|5308416

您不太可能声明一个大小为48 ^ 5或更大的数组。

答案 3 :(得分:0)

不,正则表达式无法计算倍数(一元数系统除外:十进制4 =一元1111;十进制8 =一元11111111,所以正则表达式^(1111)+$匹配4)的倍数。

答案 4 :(得分:0)

import re

# For real example,
# construction of a chain with integers multiples of 48 
# and integers not multiple of 48.
from random import *
w   =   [ 48*randint( 1,10) for j in xrange(10) ]
w.extend( 48*randint(11,20) for j in xrange(10) )
w.extend( 48*randint(21,70) for j in xrange(10) )
a = [ el if el%48!=0 else el+1 for el in sample(xrange(1000),40) ]
w.extend(a)
shuffle(w)
texte = [ ''.join(sample('     abcdefghijklmonopqrstuvwxyz',randint(1,7))) for i in xrange(40) ]
X = ''.join(texte[i]+str(w[i]) for i in xrange(40))


# Searching the multiples of 48 in the chain X
def mult48(match):
    g1 = match.group()
    if int(g1)%48==0:
        return ( g1, X[0:match.end()] )
    else:
        return ( g1, 'not multiple')

for match in re.finditer('\d+',X):
    print '%s  %s\n' % mult48(match)

答案 5 :(得分:-2)

任何倍数都很困难,但这里是一个(python风格)正则表达式,匹配48的前200个倍数。

0$|1(?:0(?:08$|56$)|1(?:04$|52$)|2(?:00$|48$|96$)|3(?:44$|92$)|4(?:4(?:$|0$)|88$\
)|5(?:36$|84$)|6(?:32$|80$)|7(?:28$|76$)|8(?:24$|72$)|9(?:2(?:$|0$)|68$))|2(?:0(\
?:16$|64$)|1(?:12$|60$)|2(?:08$|56$)|3(?:04$|52$)|4(?:0(?:$|0$)|48$|96$)|5(?:44$\
|92$)|6(?:40$|88$)|7(?:36$|84$)|8(?:32$|8(?:$|0$))|9(?:28$|76$))|3(?:0(?:24$|72$\
)|1(?:20$|68$)|2(?:16$|64$)|3(?:12$|6(?:$|0$))|4(?:08$|56$)|5(?:04$|52$)|6(?:00$\
|48$|96$)|7(?:44$|92$)|8(?:4(?:$|0$)|88$)|9(?:36$|84$))|4(?:0(?:32$|80$)|1(?:28$\
|76$)|2(?:24$|72$)|3(?:2(?:$|0$)|68$)|4(?:16$|64$)|5(?:12$|60$)|6(?:08$|56$)|7(?\
:04$|52$)|8(?:$|0(?:$|0$)|48$|96$)|9(?:44$|92$))|5(?:0(?:40$|88$)|1(?:36$|84$)|2\
(?:32$|8(?:$|0$))|3(?:28$|76$)|4(?:24$|72$)|5(?:20$|68$)|6(?:16$|64$)|7(?:12$|6(\
?:$|0$))|8(?:08$|56$)|9(?:04$|52$))|6(?:0(?:00$|48$|96$)|1(?:44$|92$)|2(?:4(?:$|\
0$)|88$)|3(?:36$|84$)|4(?:32$|80$)|5(?:28$|76$)|6(?:24$|72$)|7(?:2(?:$|0$)|68$)|\
8(?:16$|64$)|9(?:12$|60$))|7(?:0(?:08$|56$)|1(?:04$|52$)|2(?:0(?:$|0$)|48$|96$)|\
3(?:44$|92$)|4(?:40$|88$)|5(?:36$|84$)|6(?:32$|8(?:$|0$))|7(?:28$|76$)|8(?:24$|7\
2$)|9(?:20$|68$))|8(?:0(?:16$|64$)|1(?:12$|6(?:$|0$))|2(?:08$|56$)|3(?:04$|52$)|\
4(?:00$|48$|96$)|5(?:44$|92$)|6(?:4(?:$|0$)|88$)|7(?:36$|84$)|8(?:32$|80$)|9(?:2\
8$|76$))|9(?:0(?:24$|72$)|1(?:2(?:$|0$)|68$)|2(?:16$|64$)|3(?:12$|60$)|4(?:08$|5\
6$)|5(?:04$|52$)|6(?:$|0$))