用正则表达式实现查出二进制数是3的倍数

import java.util.regex.Pattern;

public class BinaryRegexp {
    public static Pattern multipleOf3() {
        // Regular expression that matches binary inputs that are multiple of 3
        return Pattern.compile("^(0+|0*1((10*1)|(01*0))*10*)$");
//下面是codwars上给出的最佳答案
        //return Pattern.compile("0*(1(01*0)*10*)*");
    }
}

reg = /^(0+|0*1((10*1)|(01*0))10)$/
其中
0+表示字符串可以全为0
第一个0*表示字符串可以以0开头
核心的句式是:1((10*1)|(01*0))10)
原理如下:
一个二进制数后面加一个“0”相当于该数乘以2,一个二进制数后面加一个“1”相当于该数乘2加1。
设定三个状态,分别叫做0、1和2,它们表示当前的数除以3所得的余数。有以下的几种可能:
0@0 => 0 表示状态0后面是0时,变成状态0
0@1 => 0 表示状态0后面是1时,变成状态1
1@0 => 2 表示状态1后面是0时,变成状态2
1@1 => 0 表示状态1后面是1时,变成状态0
2@0 => 1 表示状态2后面是0时,变成状态1
2@1 => 2 表示状态2后面是1时,变成状态2
状态0既是我们的初始状态,也是我们的最终状态。我们的自动机就做好了。现在,假如二进制数10010走进来了。从状态0出发,机器首先读到一个“1”,于是当前位置挪到状态1,表明目前该数模3余1;然后,系统读了一个“0”,我们紧跟着走到状态2,表明二进制数“10”被3除余2;下一步,我们回到状态1,表明“100”除以3余1;再往后,我们得知“1001”能被3整除。最后呢,我们读到一个0,“1001”的两倍当然还是能被3整除,我们依旧停留在原位。我们得到结论:二进制数10010能被3整除。
有限状态自动机是可以转化为正则表达式的。上面的这个自动机转化起来非常容易。我们可以先试着用自然语言叙述一下。首先,每个二进制数第一位必然为“1”。到达状态1后,我们可以随意地、任意多次地在状态1周围绕圈圈,最终回到状态1。临近末尾,我们再读到一个“1”返回状态0,这之后随便读多少个“0”都可以了。现在问题分解为:我们又如何用正则表达式表述“从状态1出发随意地走最终回到状态1”呢?在本例中,这是很好描述的:它可以是字符串“1000..001”和“0111..110”的任意组合。把这些东西用正则表达式写出来,就是我们刚才那个神秘的式子:1((10*1)|(01*0))10

Regex Testor Version 1.02 Copyright (c) 2013 Fiery Red - flameleo 我们在使用正则表达式( regex: regular expression )的过程中,经常发现正则表达式的语法很令人头疼,即使对经常使用它的人来说也是如此。对于刚接触正则表达式的人来说多练习,多使用,才能熟练掌握正则表达式。 由于难于读写,容易出错,且需要反复练习。所以找一种工具对正则表达式对我们脑中构思的regex进行测试是很有必要的。 1.特点 a.适合初学者,在不断测试用学习如何使用正则表达式。 b.可以分组保存,测试中用到的正则表达式。 c.本工具使用最常见的regex。以下是简单示例: a|b Matches a or b gr(a|e)y Matches a or e . Matches any single character [abc] Matches a single character a, b or c [^abc] Matches any single character except a, b or c [a-z] Matches a single charactor in the range a to z [a-zA-Z] Matches a single charactor in the range a to z or A to Z ^ Matches the start of the filename $ Matches the end of the filename * Matches the preceding element zero or more times ? Matches the preceding element zero or one times + Matches the preceding element one or more times {x} Matches the preceding element x times {x,} Matches the preceding element x or more times {x,y} Matches the preceding element between x and y times 值得一提的是()代表子匹配,有些环境中gr(a|e)y Matches gray or grey 还支持许多常见的转义字符 \b,\B,\c,\d,\D,\f,\n,\r,\s,\S,\t,\v,\w,\W,\x,\u 具体详见附件 Regular Expression Syntax1.html 2.功能介绍 a.界面上显示提供regex输入框和原文本框,点击[模式匹配]按钮后,会在右侧输出结果,包括匹配字符串列表和文本。 b.对于测试中一些有用的regex,点击[insert]按钮添加到模式列表,以备日后使用。你可以位该regex添加描述分组,该信息会在程序结束后保存在CustomPatternInfo.ini文件中。 c.可以参考Readme_1.jpq和Readme_2.jpq图片介绍。 3.有待改进 a.界面布局和控件友好型和交互性。 b.界面功能提供regex语法支持。(暂时可以通过导入附件RegexSystax.ini到CustomPatternInfo.ini中) 4.意见反馈 a.请将您的宝贵意见反馈到 FieryRed_2012@163.com 附件: Readme.txt Readme_1.jpg Readme_2.jpg Regular Expression Syntax.html RegexSystax.ini
### 回答1: 可以使用Python的re模块中的正则表达式来判断二进制子网掩码的合法性。以下是一个示例代码: ```python import re def is_binary_subnet_mask(mask): # 使用正则表达式匹配是否为二进制数 if not re.match(r'^[01]{32}$', mask): return False # 判断是否为连续的1 if not re.match(r'^1*0*$', mask): return False return True ``` 在上面的代码中,我们首先使用正则表达式 `^[01]{32}$` 来匹配一个32位的二进制数。然后,使用正则表达式 `^1*0*$` 来判断是否为连续的1和后面跟着连续的0,这是一个二进制子网掩码的特征。 使用示例: ```python >>> is_binary_subnet_mask('11111111111111111111111100000000') True >>> is_binary_subnet_mask('11111111111111111111111110000000') False >>> is_binary_subnet_mask('11111111111111111111111111111111') False >>> is_binary_subnet_mask('10000000111111111111111111111111') False ``` ### 回答2: 在Python中,可以使用正则表达式判断二进制子网掩码的合法性。二进制子网掩码是一个32位的二进制数,表示IP地址中网络部分和主机部分的划分。 由于二进制子网掩码的规则非常具体,可以用正则表达式来匹配并判断其合法性。 先定义以下二进制子网掩码的合法规则: 1. 二进制子网掩码必须是32位的二进制数; 2. 子网掩码的网络部分必须连续地由“1”构成,主机部分必须连续地由“0”构成; 3. 子网掩码的网络部分和主机部分的交界处可以由“0”或者由“1”组成。 根据上述规则,可以使用如下正则表达式来判断一个二进制子网掩码的合法性: ```python import re def is_valid_subnet_mask(binary_mask): pattern = r"^(1{1,32})|(0{1,32})$" result = re.match(pattern, binary_mask) if result: return True else: return False ``` 在代码中,使用了正则表达式的匹配方法`re.match()`来判断输入的二进制子网掩码是否满足规则。其中,正则表达式的`^`表示开头,`$`表示结尾,`1{1,32}`表示1可以重复1到32次,`0{1,32}`表示0可以重复1到32次。 通过调用`is_valid_subnet_mask`函数并传入二进制子网掩码,即可判断该子网掩码的合法性。如果返回值为True,则该二进制子网掩码合法;如果返回值为False,则该子网掩码不合法。 这样,我们就可以使用正则表达式来判断一个二进制子网掩码的合法性了。 ### 回答3: Python中可以使用正则表达式来判断二进制子网掩码的合法性。正则表达式是一种字符串匹配的工具,可以用来验证特定的模式是否存在于文本中。 下面是一个使用正则表达式判断二进制子网掩码合法性的示例代码: ```python import re def is_valid_subnet_mask(subnet_mask): pattern = r'^(([01]{8})\.){3}([01]{8})$' # 匹配一个由四个八位二进制数字组成的字符串,每个数字之间用点号分隔 if re.match(pattern, subnet_mask): return True else: return False # 测试 subnet_mask1 = '11111111.11111111.11111111.00000000' subnet_mask2 = '11111111.11111111.11110000.00000000' subnet_mask3 = '11111111.11110000.00000000.00000000' subnet_mask4 = '11110000.00000000.00000000.00000000' print(is_valid_subnet_mask(subnet_mask1)) # 输出:True print(is_valid_subnet_mask(subnet_mask2)) # 输出:True print(is_valid_subnet_mask(subnet_mask3)) # 输出:True print(is_valid_subnet_mask(subnet_mask4)) # 输出:True ``` 该代码中,使用了正则表达式的匹配功能来判断传入的字符串是否符合特定的模式。正则表达式的模式包括了四个八位二进制数字,每个数字之间由点号分隔。最终返回True表示合法,返回False表示不合法。 通过这种方式,我们可以使用Python的正则表达式模块re来方便地进行二进制子网掩码合法性的判断。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值