week4:函式之正則表示式
阿新 • • 發佈:2018-11-10
一、正則表示式
string提供的方法是完全匹配
引入正則表示式是模糊匹配,內嵌在python中,通過呼叫Re模組來實現
二、字元匹配(普通字元,元字元):
普通字元:大多數字符和字母都會和自身匹配
re.findall('alex','yuanalesalexduye') ## 完全匹配
元字元:. ^ $ * + ? {} [] | () \
import re ret = re.findall('w\w{2}l', 'hello world') #['worl'] print(ret)
import re
#. 萬用字元
ret = re.findall('w..l', 'hello world')
print(ret) ##['worl'] 只能代指任意一個字元 不能代指換行符
import re
ret = re.findall('^w..l', 'wuylhello world')
print(ret) ##['wuyl'] 從開始匹配
import re
ret = re.findall('w..l$', 'wuylhello world')
print(ret) ##[] 從結束匹配
import re # * 重複匹配 [0 oo] 重複前面字元的個數 貪婪匹配 ret = re.findall('w.*l', 'wuylhello world') print(ret) ##
import re
# + 重複匹配 [1 oo] 貪婪匹配
ret = re.findall('w+l', 'wwlhello world')
print(ret) ##
# ? 重複匹配 [0 1]
# {n} n匹配
#{n1,n2} n1 n2匹配 貪婪匹配
# [] 字符集 取消元字元的特殊功能(\ ^ -這3個字元例外) import re ret = re.findall('a[c,d]x', 'acx') print(ret)##['acx'] #-放在[]裡,代表範圍 ret1 = re.findall('[a-z]x', 'acx') print(ret1) #['cx'] ret3 = re.findall('[1-9a-zA-Z]', '12tyAS') print(ret3) #['1', '2', 't', 'y', 'A', 'S'] ret4 = re.findall('[1-9,a-z,A-Z]', '12tyAS') print(ret4) #['1', '2', 't', 'y', 'A', 'S'] #特殊字元. * 沒有特殊意義 ret2 = re.findall('[w,*]x', 'acx') print(ret2) #[] #^放在[]裡,代表取反 ret5 = re.findall('[^4,5]', 'ju12tyA5i4,us') print(ret5) #['j', 'u', '1', '2', 't', 'y', 'A', 'i', 'u', 's'] # \ 後邊跟元字元,去特殊功能 #\ 後邊跟普通字元,實現特殊功能 ret6 = re.findall('\d{11}', 'ju12tyA5i498234567812345678') print(ret6) #['j', 'u', '1', '2', 't', 'y', 'A', 'i', 'u', 's'] ret7 = re.findall(r'I\b', 'I am a LIST') print(ret7) #['I'] #匹配出第一個滿足條件的結果 ret8 = re.search('s.b', 'fjaskdseb') print(ret8.group()) #seb ret9 = re.search('a\.', 'agj') print(ret9.group()) #此時沒有匹配成功
import re
# ()|
ret9 = re.search('(as)+', 'agjasas')
print(ret9.group())
ret10 = re.search('(as)|3', '3agjasas')
print(ret10.group()) ##3
三、正則表示式的方法
1、findall() 所有的結果都返回到一個列表裡
2、search() 返回匹配到的第一個物件(object),物件可以呼叫group返回結果
3、match() 只在字串開始匹配,物件可以呼叫group返回結果
import re
ret = re.match('asd', 'asdfeuyrt')
print(ret.group())
4、split()
import re
ret = re.split('[j,s]', 'djksal')
print(ret)
5、sub()
import re
ret = re.sub('a..x', 's..b', 'djkalexsal')
print(ret) ##djks..bsal
6.compile()
import re
obj = re.compile('.com')
ret = obj.findall('djkal.comexsal')
print(ret) ##['.com']
四、正則表示式的應用
計算器的設計
import re
#格式化字串
def format_string(string):
string = string.replace('--', '+')
string = string.replace('-+', '-')
string = string.replace('++', '+')
string = string.replace('+-', '-')
string = string.replace('*+', '*')
string = string.replace('/+', '/')
string = string.replace(' ', '')
return string
#檢查表示式合法性
def check_expression(string):
check_result = True
#括號是否匹配
if not string.count('(') == string.count(')'):
print('表示式錯誤,括號未閉合')
check_result = False
if re.findall('[a-z]+]',string.lower()):
print('表示式錯誤,包含非法字元')
check_result = False
return check_result
#計算乘除
def calc_mul_div(string):
#從字串中獲取一個乘法或除法的表示式
regular = '[\-]?\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
#如果還能找到乘法或除法表示式
while re.findall(regular, string):
#獲取表示式
expression = re.search(regular, string).group()
#如果是乘法
if expression.count('*')==1:
#獲取要計算的兩個數
x, y = expression.split('*')
#計算結果
mul_result = str(float(x)*float(y))
#將計算的表示式替換為計算結果值
string = string.replace(expression, mul_result)
#格式化以下
string = format_string(string)
#如果是除法
if expression.count('/'):
#獲取要計算的兩個數
x, y = expression.split('/')
#計算結果
div_result = str(float(x)/float(y))
#將計算的表示式替換為計算結果值
string = string.replace(expression, div_result)
#格式化以下
string = format_string(string)
if expression.count('*')==2:
#獲取要計算的兩個數
x, y = expression.split('**')
pow_result=1
for i in range(int(y)):
pow_result *= int(x)
string = string.replace(expression, str(pow_result))
#格式化以下
string = format_string(string)
return string
#計算加減
def calc_add_sub(string):
#定義正則表示式
add_regula = '[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
sub_regula = '[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
#開始加法
while re.findall(add_regula, string):
#把所有的加法都算完,獲取所有加法表示式
add_list = re.findall(add_regula, string)
for add_str in add_list:
#獲取兩個加法的數
x, y = add_str.split('+')
add_result = '+' + str(float(x)+float(y))
string = string.replace(add_str, add_result)
string = format_string(string)
# 開始減法
while re.findall(sub_regula, string):
#把所有的加法都算完,獲取所有加法表示式
sub_list = re.findall(sub_regula, string)
for sub_str in sub_list:
numbers = sub_str.split('-')
#-3-5的情況,split會返回3個值
if len(numbers) == 3:
result = 0
for v in numbers:
if v:
result -= float(v)
else:
x, y =numbers
result = float(x)-float(y)
#替換字串
string = string.replace(sub_str, '+' + str(result))
string = format_string(string)
return string
if __name__ == "__main__":
source = "30-2*(6-3+(-9+2*3-4*4/2+6*3))"
if check_expression(source):
print('source:', source)
print('eval result:', eval(source))
source = format_string(source)
print(source)
while source.count('(') > 0:
## 格式化
##去括號,得到括號的字串,結果如:(30+6/3)
strs = re.search('\([^()]*\)', source).group()
# 將括號的表示式進行乘除運算
replace_str = calc_mul_div(strs)
# 將括號的表示式進行加減運算
replace_str = calc_add_sub(replace_str)
# 將括號的字串替換為計算結果,結果包含(),替換時去掉():[1:-1]
source = format_string(source.replace(strs, replace_str[1:-1]))
else:
# 沒有括號就到最後單一表達式了
replace_str = calc_mul_div(source)
# 算乘除
replace_str = calc_add_sub(replace_str)
# 算加減
source = source.replace(source, replace_str)
print('my result:', source.replace('+', ''))
輸出結果:
source: 30-2*(6-3+(-9+2*3-4*4/2+6*3))
eval result: 10.0
30-2*(6-3+(-9+2*3-4*4/2+6*3))
my result: 10.0