最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用正則實(shí)現(xiàn)計(jì)算字符串算式

 更新時(shí)間:2019年12月29日 09:05:19   作者:南柯33  
這篇文章主要介紹了Python使用正則實(shí)現(xiàn)計(jì)算字符串算式的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

在Python里面其實(shí)有一種特別方便實(shí)用的直接計(jì)算字符串算式的方法

那就是eval()

s = '1+2*(6/2-9+3*(3*9-9))'
print(eval(s))
#97.0

好了,我現(xiàn)在就是想用正則寫一個(gè)類似這樣功能的東西

第一步,我們拿到一個(gè)算式,例如'1+2*(6/2-9+3*(3*9-9))'

按照我們小學(xué)學(xué)的知識(shí)我們應(yīng)該知道我們應(yīng)該從最內(nèi)層括號(hào)里面的算式開始計(jì)算

那我們?cè)趺茨玫阶顑?nèi)層括號(hào)里面的算式呢?我們可以用正則啊

import re
pattern = re.compile(r'\([^(^)]*?\)')
s = '1+2*(6/2-9+3*(3*9-9))+(6-3)'
ret = pattern.findall(s)
print(ret)
#['(3*9-9)','(6-3)']

好了,我們現(xiàn)在就拿到了最內(nèi)層括號(hào)以及里面的算式了,第一步完成

第二步,我們要把拿到的內(nèi)容給它去掉括號(hào)

因?yàn)槲覀兡玫降淖顑?nèi)層的括號(hào)可能不止一個(gè),所以我們用一個(gè)新的列表來存一下去掉括號(hào)里面的算式

ret2 = []
pattern2 = re.compile(r'\((?P<tag>.*?)\)')
for i in range(len(ret)):
 ret3 = pattern2.search(ret[i])
 ret2.append(ret3.group('tag'))
print(ret2)
#['3*9-9', '6-3']

其實(shí)到這里我們幾乎已經(jīng)成功一大半了

第三步,我們就要來安排我們拿到的最內(nèi)層括號(hào)的算式了

這里只展示邏輯,我就只拿'3*9-9'(ret2[1])來說了

我們還是得根據(jù)算術(shù)邏輯來,先乘除,后加減

乘除

def mul_div(s):
 if '*' in s:
 s = s.split('*')
 return float(s[0]) * float(s[1])
 elif '/' in s:
 s = s.split('/')
 return float(s[0]) / float(s[1])
while True:
 pattern3 = re.compile(r'[-+*/]?(?P<tag>-?\d+(\.\d+)?[*/]-?\d+(\.\d+)?)')
 ret3 = pattern3.search(ret2[1])
 try:
 ret4 = ret3.group('tag')
 except Exception as e:
 pass
 if '*' not in ret2[1] and '/' not in ret2[1]:
 break 
 else:
 ret2[1] = ret2[1].replace(ret4, str(mul_div(ret4)))

這里的代碼,可能看不明白,我來解釋一下

首先mul_div()就是自己定義的一個(gè)計(jì)算乘除法的方法

因?yàn)檎齽t表達(dá)式的約束,并且用的是search,所以一下得到的字符串只可能是字符+'/'+字符或者字符+'*'+字符。所以這里字符串切割,必定會(huì)根據(jù)乘除號(hào)切成兩個(gè)元素的列表

我們算出了字符+'/'+字符或者字符+'*'+字符的值,我們就要用算出來的值替換掉正則匹配的字符串,直到這個(gè)字符串中沒有乘除號(hào)

加減

def add_sub(s):
 if '+' in s:
 s = s.split('+')
 return float(s[0]) + float(s[1])
 else:
 if s[0] == '-':
  s = s[1::].split('-', 1)
  s[0] = '-' + s[0]
  return float(s[0]) - float(s[1])
 else:
  s = s.split('-', 1)
  return float(s[0]) - float(s[1])
while True:
 pattern3 = re.compile(r'-?\d+(\.\d+)?[-+]-?\d+(\.\d+)?')
 ret3 = pattern3.search(ret2[i])
 try:
 ret4 = ret3.group()
 except Exception as e:
 pass
 if '+' not in ret2[i] and '-' not in ret2[i][1::]:
 break
 else:
 ret2[i] = ret2[i].replace(ret4, str(add_sub(ret4)))

加減法和上面的乘除法沒多少區(qū)別

唯一的區(qū)別就是判斷退出時(shí),一個(gè)數(shù)可能是負(fù)數(shù),就不能直接判斷負(fù)號(hào)存不存在了,就要判斷除了第一個(gè)位置,其余的位置還存不存在負(fù)號(hào)

第四步

在這里,我們所有最內(nèi)層括號(hào)算出來的數(shù)都在ret2這個(gè)列表里面,我們r(jià)et1中存放的是最內(nèi)層括號(hào)以及里面的算式,所以我們將兩者替換就可以了

def str_replace(lst1,lst2):
 for i in range(len(lst1)):
 global str1
 str1 = str1.replace(lst1[i], lst2[i])
 
str_replace(ret1,ret2)

第五步

其實(shí)到這里我們離成功就差一小步了

可能你已經(jīng)發(fā)現(xiàn)了,我們這一套下來,就是對(duì)一個(gè)括號(hào)內(nèi)的算式進(jìn)行運(yùn)算,如果沒有括號(hào)它最后就不會(huì)對(duì)它進(jìn)行操作,那我們就在字符串進(jìn)來的時(shí)候給最外層套一個(gè)括號(hào)就OK了

str1 = '1+2*(6/2-9+3*(3*9-9))'
str1 = '( )'.replace(' ',str1)

然后拿到一個(gè)算式一直重復(fù)上面的幾個(gè)步驟,直到?jīng)]有括號(hào)。

完整代碼

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
# 乘除法
def mul_div(s):
 if '*' in s:
 s = s.split('*')
 return float(s[0]) * float(s[1])
 elif '/' in s:
 s = s.split('/')
 return float(s[0]) / float(s[1])
# 加減法
def add_sub(s):
 if '+' in s:
 s = s.split('+')
 return float(s[0]) + float(s[1])
 else:
 if s[0] == '-':
  s = s[1::].split('-', 1)
  s[0] = '-' + s[0]
  return float(s[0]) - float(s[1])
 else:
  s = s.split('-', 1)
  return float(s[0]) - float(s[1])
# 替換字符串
def str_replace(lst1,lst2):
 for i in range(len(lst1)):
 global str1
 str1 = str1.replace(lst1[i], lst2[i])
# 匹配最內(nèi)層括號(hào)
pattern1 = re.compile(r'\([^(^)]*?\)')
str1 = '1+2*(6/2-9+3*(3*9-9))'
str1 = '( )'.replace(' ',str1)
while True:
 if '(' not in str1 and ')' not in str1:
 break
 ret1 = pattern1.findall(str1)
 # 匹配括號(hào)內(nèi)的內(nèi)容
 ret2 = []
 pattern2 = re.compile(r'\((?P<tag>.*?)\)')
 for i in range(len(ret1)):
 ret = pattern2.search(ret1[i])
 ret2.append(ret.group('tag'))
 # 計(jì)算乘除法
 while True:
  pattern3 = re.compile(r'[-+*/]?(?P<tag>-?\d+(\.\d+)?[*/]-?\d+(\.\d+)?)')
  ret3 = pattern3.search(ret2[i])
  try:
  ret4 = ret3.group('tag')
  except Exception as e:
  pass
  if '*' not in ret2[i] and '/' not in ret2[i]:
  break
  else:
  ret2[i] = ret2[i].replace(ret4, str(mul_div(ret4)))
 # 計(jì)算加法
 while True:
  pattern3 = re.compile(r'-?\d+(\.\d+)?[-+]-?\d+(\.\d+)?')
  ret3 = pattern3.search(ret2[i])
  try:
  ret4 = ret3.group()
  except Exception as e:
  pass
  if '+' not in ret2[i] and '-' not in ret2[i][1::]:
  break
  else:
  ret2[i] = ret2[i].replace(ret4, str(add_sub(ret4)))
 str_replace(ret1,ret2)
print(str1)
#97.0

結(jié)束語

希望以后有人看到了,就不要吐槽我的ret1-ret4的變量命名了

還有不知道有沒有寫清楚,看的人能不能看明白,畢竟一晚上沒睡覺,可能腦子不好使。

我這代碼肯定有很多值得優(yōu)化的地方,所以僅供參考。

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

總結(jié)

以上所述是小編給大家介紹的Python使用正則實(shí)現(xiàn)計(jì)算字符串算式,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • 使用Python的time庫格式化時(shí)間的方法

    使用Python的time庫格式化時(shí)間的方法

    通過使用Python的time庫,我們可以方便地進(jìn)行時(shí)間處理、格式化、解析和計(jì)算等操作,本文介紹了time庫的一些常見功能和使用方法,包括格式化時(shí)間、解析時(shí)間戳、獲取當(dāng)前時(shí)間、計(jì)算時(shí)間差等,感興趣的朋友一起看看吧
    2023-11-11
  • 使用matlab讀取含表頭csv文件

    使用matlab讀取含表頭csv文件

    這篇文章主要介紹了使用matlab讀取含表頭csv文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • wxPython多個(gè)窗口的基本結(jié)構(gòu)

    wxPython多個(gè)窗口的基本結(jié)構(gòu)

    這篇文章主要為大家詳細(xì)介紹了wxPython多個(gè)窗口的基本結(jié)構(gòu),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Python音樂爬蟲完美繞過反爬

    Python音樂爬蟲完美繞過反爬

    這篇文章主要介紹了Python音樂爬蟲完美繞過反爬的過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • 淺談Selenium 控制瀏覽器的常用方法

    淺談Selenium 控制瀏覽器的常用方法

    這篇文章主要介紹了淺談Selenium 控制瀏覽器的常用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 詳解Python中import機(jī)制

    詳解Python中import機(jī)制

    這篇文章主要介紹了Python中import機(jī)制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下
    2020-09-09
  • 對(duì)pytorch中不定長(zhǎng)序列補(bǔ)齊的操作

    對(duì)pytorch中不定長(zhǎng)序列補(bǔ)齊的操作

    這篇文章主要介紹了對(duì)pytorch中不定長(zhǎng)序列補(bǔ)齊的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • Python多線程Threading、子線程與守護(hù)線程實(shí)例詳解

    Python多線程Threading、子線程與守護(hù)線程實(shí)例詳解

    這篇文章主要介紹了Python多線程Threading、子線程與守護(hù)線程,結(jié)合實(shí)例形式詳細(xì)分析了Python多線程Threading、子線程與守護(hù)線程相關(guān)概念、原理、用法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • Python線性回歸實(shí)戰(zhàn)分析

    Python線性回歸實(shí)戰(zhàn)分析

    這篇文章主要介紹了Python線性回歸實(shí)戰(zhàn)分析以及代碼講解,對(duì)此有興趣的朋友學(xué)習(xí)下吧。
    2018-02-02
  • 使用 Django Highcharts 實(shí)現(xiàn)數(shù)據(jù)可視化過程解析

    使用 Django Highcharts 實(shí)現(xiàn)數(shù)據(jù)可視化過程解析

    這篇文章主要介紹了使用 Django Highcharts 實(shí)現(xiàn)數(shù)據(jù)可視化過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07

最新評(píng)論

泸州市| 武安市| 卢龙县| 台南县| 沭阳县| 台南县| 宝坻区| 峨边| 扶沟县| 炎陵县| 六枝特区| 栾城县| 连平县| 两当县| 怀集县| 襄樊市| 广平县| 隆安县| 常宁市| 莎车县| 嘉峪关市| 师宗县| 嫩江县| 施甸县| 哈密市| 略阳县| 徐汇区| 孝义市| 宁陵县| 腾冲县| 绥滨县| 宽城| 兴业县| 蒙城县| 商南县| 永修县| 洛隆县| 南宁市| 吉林省| 韶山市| 赫章县|