技术问询:求匹配4的倍数的正则表达式及检测该数的词法分析器
匹配能被4整除的数字的正则表达式与词法分析器实现
一、匹配能被4整除的数字的正则表达式
先给你理清楚核心规则:一个整数能被4整除,要么是一位数的0、4、8;要么是两位数及以上时,最后两位组成的数能被4整除。基于这个逻辑,分两种常用场景给你对应的正则:
场景1:允许前导零(比如0016这类格式)
^(0|4|8|\d*(0[048]|1[26]|2[048]|3[26]|4[048]|5[26]|6[048]|7[26]|8[048]|9[26]))$
- 拆解下逻辑:
0|4|8:直接匹配单个能被4整除的一位数\d*:匹配任意数量的前置数字(包括零个,刚好对应两位数的情况)0[048]|1[26]|...|9[26]:枚举所有能被4整除的两位数组合(比如00、04、12、96这些)
场景2:不允许前导零(仅匹配常规合法整数)
如果要避免像0016这种不符合常规书写的情况,正则调整为:
^([1-9]\d*(0[048]|1[26]|2[048]|3[26]|4[048]|5[26]|6[048]|7[26]|8[048]|9[26])|0|4|8)$
- 核心区别是用
[1-9]\d*替代了\d*,确保多位数的开头是非零数字,符合常规整数的书写规范。
二、能被4整除的数字的词法分析器(Flex实现)
你给出的示例是Flex(词法分析生成器)的雏形,不过规则部分需要调整,要把正则表达式放在动作前面。下面是完整可运行的代码:
%% # 匹配能被4整除的数字(不允许前导零) ([1-9][0-9]*(0[048]|1[26]|2[048]|3[26]|4[048]|5[26]|6[048]|7[26]|8[048]|9[26])|0|4|8) { printf("divisible by 4 %s\n", yytext); } # 匹配其他所有字符,不做处理(避免程序报错) .|\n {} %% int main() { yylex(); return 0; }
代码说明:
- 规则部分:
- 第一个规则用了上面“不允许前导零”的正则,匹配到符合条件的数字后,打印提示信息并输出当前匹配到的文本(
yytext是Flex的内置变量,存储当前匹配的字符串)。 - 第二个规则匹配任意单个字符或换行,动作留空,这样遇到非目标数字时不会触发错误提示。
- 第一个规则用了上面“不允许前导零”的正则,匹配到符合条件的数字后,打印提示信息并输出当前匹配到的文本(
- 主函数:调用
yylex()启动词法分析器,程序会持续读取输入,直到遇到EOF(比如按下Ctrl+D)。
编译运行步骤:
- 把代码保存为
div4.l - 用Flex编译:
flex div4.l,会生成lex.yy.c文件 - 用C编译器编译:
gcc lex.yy.c -o div4 - 运行程序:
./div4,输入数字回车,符合条件的就会输出提示啦!
内容的提问来源于stack exchange,提问作者user8874182
相关产品推荐
相关产品推荐

