四时宝库

程序员的知识宝库

python编程小练习——帮助掌握正则表达式,锻炼编程能力

今天尝试做了一道与正则表达式密切相关的编程练习题:计算字符串四则运算式。有兴趣深入学python的朋友可以跟着我一起尝试。在做练习之前推荐打开http://tool.chinaz.com/regex网页,这里有正则测试工具,编写完的正则表达式可以去那里测试是否正确。

请尝试计算字符串四则运算式。注意代码内可使用2个数的±*/,但不能用python的表达式功能运算表达式,也不能用eval函数运算。字符串四则运算式示例如下:

compute = '10-3*(20-10+(-10/5)*27/3/3-(-100)/(10-3*5))+(-2.5*-12)'

练习第一步,匹配数字:

匹配数字(含正整数、负整数、正浮点数、负浮点数):

-?\d+(\.\d+)?

可以测试匹配123、-123、1.23、-1.23均成功。

表达式解析

-?表示匹配-,?表示0个或1个。

\d+表示匹配数字,+表示1个或多个。

(\.\d+)?这部分最复杂,一步步来解释。括号内是\.表示匹配小数点(若不加\则会匹配为除换行符外任意字符);\d+同上;一对圆括号后面跟?表示这些内容可能不出现或出现1次,意思是可以匹配小数点及后面1个或多个数字也匹配无小数点及后面的数字。

上述正则表达式经站长工具网站测试没有问题,但是在python中代码中会有问题,请看下面的代码示例:

num1 = 'The number is 123 ?'
num2 = 'The number is -123 ?'
num3 = 'The number is 1.23 ?'
num4 = 'The number is -123 ?'
dig1 = re.compile('-?\d+(\.\d+)?')
dig2 = re.compile('-?\d+(?:\.\d+)?')
print(dig1.findall(num1))
print(dig1.findall(num2))
print(dig1.findall(num3))
print(dig1.findall(num4))
print(dig2.findall(num1))
print(dig2.findall(num2))
print(dig2.findall(num3))
print(dig2.findall(num4))

out:
['']
['']
['.23']
['']
['123']
['-123']
['1.23']
['-123']

认真阅读代码,可以看到findall函数使用dig1正则表达式字符串提取不到数字,而dig1正则表达式明明已经验证过是正确的,为什么会提取不到数字呢?

这其中的原因是因为分组概念冲突!正则表达式的分组使用圆括号表示,而re模块的分组也使用圆括号表示,请认真理解这2种分组概念是不同的之处,非常重要!!!

正则表达式的分组是把某一段表达式进行整体包装,然后可对该整体做操作,如或|和范围.?*{m,n}。

re模块的分组是指对正则表达式匹配的内容再次筛选,只需要分组内匹配的部分内容。

解决方法是对正则表达式的分组左括号后面加?:实施分组隐藏,告诉python解释器这个分组不是使用再次筛选的意思。

练习第二步,匹配内层括号中的内容

接下来尝试匹配四则运算字符串中内层括号之中的内容:

compute = '10-3*(20-10+(-10/5)*27/3/3-(-100)/(10-3*5))+(-5*-6)'

匹配最内层括号

[\d.?/±]+?[\d.?/±]+?

在站长工具网站测试可以成功匹配出以下内容:

(-10/5)、(-100)、(10-3*5)、(-5*-6)

表达式解析

先匹配外面的圆括号,注意都要用\转义,然后观察目标字符串的规律填写括号中的内容。

括号中可以有的字符集是数字、小数点、加、减、乘、除,可以出现1次或多次,注意必须加在量词+后面写?标识为最短匹配。

再到python中测试正则表达式。

compute = '10-3*(20-10+(-10/5)*27/3/3-(-100)/(10-3*5))+(-5*-6)'
result = re.findall('\([\d\.*/+-]+?\)', compute)
print(result)

out:
['(-10/5)', '(-100)', '(10-3*5)', '(-5*-6)']

练习第三步,编写计算字符串四则运算式代码

写代码以前我以为顶多半个小时搞定,结果被打脸了。写代码用了不到半个小时,调试用了一个多小时!前后2个小时才搞定。真的是看着容易做起来难!建议学python的朋友尝试做一下这个练习。做这个练习对于掌握正则表达式和锻炼编程能力很有帮助。

编程思路、代码、调试过程我决定过几天再公布。今天先贴一张运算结果的图。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接