设为首页 收藏本站
查看: 1083|回复: 0

[经验分享] python基础:正则科学计算器问题集

[复制链接]
YunVN网友  发表于 2018-8-13 06:38:25 |阅读模式
  问题一
  str1 = re.sub("([^()])", result, str1),替换的时候会把当前到下一个)全部替换。
  查看结果是因为默认多次替换原因导致
  str1 = re.sub("\(*[^()]*\)", result, str1, count=1)
  替换一次正常
  问题二:
  怎么精确的寻到一个-+,++,*+,/+等等的双重符号。。。像下面这样每句替换吗?
  

str1 = re.sub("++", "+",str1)  
str1 = re.sub("-+", "-",str1)
  
str1 = re.sub("*+", "*",str1)
  
str1 = re.sub("/+", "/",str1)
  

  NO,正则就是一个找规律的游戏,上面的句子完全可以一句替代:
  str1 = re.sub('\W+', re.search('\W-', str1).group()[0], str1,count=1)
  但是,上面有个问题遇到(3-2)+1,会把)+也给找出来,太不智能了,怎么办?
  试试下面的:
  str1 = re.sub('[*+/-]+', re.search('[*+/-]-', str1).group()[0], str1,count=1)
  只认这四个,完美解决了)+的问题,oh yeah~
  问题三:
  运行整数时,程序正常,运行浮点,程序就出问题,因为多了.这个非数字字符。
  问题四:
  测试完美的程序,运算作业题时报错。
  测试打印
  -->2> 1-2*((60-30-1388360.0.88095238098+1.2.0
  报错:
  

    subtotal += float(i)  
ValueError: could not convert string to float: '-2*'
  

  分析:为什么会出现乱码呢?
  测试-(-5/3(8-10)+23)+33这样公式都可以,比较一下,发现了问题
  题目的式子,是两个括号在一起的。。。。。。
  1 - 2 ( (60-30 +(-40/5) (9-25/3 + 7 /399/42998 +10 568/14 )) - (-43)/ (16-32) )
  改进后的正则:就算你有10个括号在一起,也不怕!
  r"\([^\(+][\d+\W+][^\(\)]*[\W+\d+][^\)+]\)"
  附代码:
  #!--coding:utf-8--
  import re

def parenthesis(str1)                             获取最内层括号内的表达式,并用result函数的结果替换回表达式,循环去括号

def result(str1, i=0)                             返回的是计算结果,str1是一个没有括号的表达式!



初始作业表达式
  string = '1 - 2 ( (60-30 +(-40/5) (9-25/3 + 7 /399/42998 +10 568/14 )) - (-43)/ (16-32) )'
  def result(str1, i=0):

计算没有括号的表达式结果,先算*/,再算加减。
  

while i < 2:                                # 两次,因为防止去完*- 和/-以后再次出现--/+-  i += 1
  str1 = re.sub("--", "+", str1)       # 去括号的第一步,防止-(-1)出现,做替换
  str1 = re.sub("\+-", "-", str1)      # 去括号的第二步,防止+(-1)出现,做替换
  # print('str11-->%d>'%i, str1)
  # 去掉多余的加号。
  while re.search('[\*\+/-]\+', str1):
  str1 = re.sub('[\*\+/-]\+', re.search('[\*\+/-]\+', str1).group()[0], str1, count=1)
  # 开始[*/][-]运算
  opt = re.search('\d*[\.\d]\d*[\*/][\-]*\d*[\.\d]\d*', str1)            # 查找提取*/号和前后的数字,并作为循环条件
  while opt:
  opt = opt.group()                                               # 提取字符串
  if re.search('[\*/]-', opt):                                    # 判断减号
  sub_str = re.sub('[\*/]-', re.search('[\*/]', opt).group(), opt, count=1)   # 去掉减号
  symbol = '-'
  else:                                                           # 没有减号,不做处理
  symbol = ''
  sub_str = opt
  

  arithmetic = re.search('[\*/]', sub_str).group()                # 提取运算符
  num_list = re.search('(\d*[\.\d]\d*)[\*/](\d*[\.\d]\d*)', sub_str).groups()     # 提取运算符前后的数字
  # 用运算结果,替换掉str1中对应的字符,重新赋值给str1
  str1 = re.sub('\d*[\.\d]\d*[\*/][\-]*\d*[\.\d]\d*',
  symbol+str(eval(str(num_list[0]+arithmetic+num_list[1]))), str1, count=1)
  opt = re.search('\d*[\.\d]\d*[\*/][\-]*\d*[\.\d]\d*', str1)            # 查找提取*/号和前后的数字,并作为循环条件
  

  
# 上面程序处理后,成为一个只有+-的字符串,下面处理+和-
  
if str1[0].isdigit():                       # 首位是数字,添加+号,为正则准备。
  str1 = '+' + str1
  
subtotal = 0                                # 初始化和值
  
opt = re.findall('(\W\d*[\.\d*]\d*)', str1)     # 带加减和数字的分组
  
for i in opt:                                     # 累加
  subtotal += float(i)
  
return str(subtotal)                                     # 返回计算结果
  

  def parenthesis(str1):
  str1 = re.sub(r'\s+', '', str1)
  search = re.search(r&quot;([^(+][\d+\W+][^()][\W+\d+][^)+])&quot;, str1)           # 搜索最内层括号,并作为循环条件
  while search:
  str_sub = search.group()
  temp = str_sub[1:-1]                        # 去掉括号
  result_str = result(temp)                   # 调用算术运算函数
  str1 = re.sub(r&quot;([^(+][\d+\W+][^()][\W+\d+][^)+])&quot;, result_str, str1, count=1)        # 括号内计算结果替换回去
  search = re.search(r&quot;([^(+][\d+\W+][^()]*[\W+\d+][^)+])&quot;, str1)                        # 搜索最内层括号
  return str1
  def error(str1):
  try:
  eval(str1)
  except:
  print('表达式错误!')
  return True

程序开始
  while True:
  expression = input('[Q]退出,请输入算术表达式,例如:\n%s\n-->>' % string).strip()
  if expression.lower() == 'q':
  print('退出!')
  break
  print('您输入的表达式是:', expression)
  if error(expression):
  continue
  else:
  print('正则-运算结果是:', result(parenthesis(expression)))
  print('EVAL-运算结果是:', eval(expression))
  input('按任意键继续...')

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-550836-1-1.html 上篇帖子: python爬虫——爬取古诗名句 下篇帖子: Python Web框架Django笔记(一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表