正則表達(dá)式
- 本身也和python沒有什么關(guān)系,就是匹配字符串內(nèi)容的一種規(guī)則。
- 正則表達(dá)式是對(duì)字符串操作的一種邏輯公式暂筝,就是用事先定義好的一些特定字符、及這些特定字符的組合硬贯,組成一個(gè)“規(guī)則字符串”焕襟,這個(gè)“規(guī)則字符串”用來表達(dá)對(duì)字符串的一種過濾邏輯
元字符
. 匹配除換行符以外的任意字符
\w 匹配字母或數(shù)字或下劃線
\s 匹配任意的空白符
\d 匹配數(shù)字
\n 匹配一個(gè)換行符
\t 匹配一個(gè)制表符
\b 匹配一個(gè)單詞的結(jié)尾
^ 匹配字符串的開始
$ 匹配字符串的結(jié)尾
\W 匹配非字母或數(shù)字或下劃線
\D 匹配非數(shù)字
\S 匹配非空白符
a|b 匹配字符a或字符b 左邊|右邊
() 匹配括號(hào)內(nèi)的表達(dá)式,也表示一個(gè)組
[...] 匹配字符組中的字符
[^...] 匹配除了字符組中字符的所有字符
量詞
*重復(fù)零次或更多次
+重復(fù)一次或更多次
? 重復(fù)零次或一次
{n} 重復(fù)n次
{n,} 重復(fù)n次或更多次
{n,m} 重復(fù)n到m次
兩次后面加上?就是惰性匹配
不加就是貪婪匹配
- 就是取前面任意長(zhǎng)度的字符饭豹,直到一個(gè)x出現(xiàn)
.*?x
- findall
import re
ret = re.findall('a', 'eva egon yuan') # 返回所有滿足匹配條件的結(jié)果,放在列表里
print(ret) # ['a', 'a']
# findall 有一個(gè)特點(diǎn)鸵赖,會(huì)優(yōu)先顯示分組中的內(nèi)容 (?:)取消分組優(yōu)先
# 多個(gè)分組會(huì)以[('www', 'baidu', 'com')]形式返回
ret = re.findall('\d(\.\d)?[*/]\d','1.5*5')
print(ret) # ['.5']
ret = re.findall('\d+\.\d+|\d+',"1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
ret = re.findall('(\d+\.\d+|\d+)',"1-2*(60+(-40.35/5)-(-4*3))")
print(ret) # 同上
- search
ret = re.search('\d+','SGahsf')
print(ret)
if ret:
print(ret.group())
search
返回值 : 返回一個(gè)SRE_Match對(duì)象
通過group去取值
且只包含第一個(gè)匹配到的值
ret = re.search('(www)\.(baidu|oldboy)\.(com)', 'www.baidu.com')
print(ret.group(0))
print(ret.group(1)) #第一組 顯示分組優(yōu)先
print(ret.group(2)) #第二組
print(ret.group(3)) #第三組
- 算式中匹配出最內(nèi)層小括號(hào)以及小括號(hào)內(nèi)的表達(dá)式
\([^()]+\)
- 匹配出從左到右第一個(gè)乘法或除法
#-?\d+(\.\d+)?[*/]-?\d+(\.\d+)?
ret = re.search('-?\d+(\.\d+)?[*/]-?\d+(\.\d+)?','9.0-2.22*5/3+7/3*99/4*2998+10*568/14')
print(ret.group())
# \d+(\.\d+)?[*/]-?\d+(\.\d+)?
ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?','9.0-2.22*5/3+7/3*99/4*2998+10*568/14')
print(ret.group())
- 乘除法
exp = '2*3/4*5'
import re
def mul_div(son_exp):
if '*' in son_exp:
a, b = son_exp.split('*')
mul = float(a) * float(b) # 6
return mul
elif '/' in son_exp:
a, b = son_exp.split('/')
div = float(a) / float(b) # 6
return div
while True:
ret = re.search('-?\d+(\.\d+)?[*/]-?\d+(\.\d+)?',exp)
if ret:
son_exp = ret.group() # '2*3'
res = mul_div(son_exp)
exp = exp.replace(son_exp,str(res))
else:break
print(exp,type(exp))
- match(search) 驗(yàn)證用戶輸入內(nèi)容 -->默認(rèn)從頭開始匹配,和search類似
ret = re.match('\d+','293ahs293djjk293sahf2938u')
#search 中在正則表達(dá)式中加'^'
print(ret)
#<_sre.SRE_Match object; span=(0, 3), match='293'> ..span=(0, 3)-->索引
print(ret.group())
- 切割split 有分組優(yōu)先
s1 = 'alex||egon|boss_jin'
print(s1.split('|'))
s = 'alex8123egon1120boss_jin'
ret = re.split('\d+',s)
print(ret) # ['alex', 'egon', 'boss_jin']
ret = re.split('(\d+)',s) # (\d)+ 相當(dāng)于\d\d\d\d\d...(\d)
print(ret) # ['alex', '8123', 'egon', '1120', 'boss_jin']
ret = re.split('\d(\d)',s)
print(ret) # ['alex', '1', '', '3', 'egon', '1', '', '0', 'boss_jin']
- 替換sub(replace)
s = 'alex|egon|boss_jin'
print(s.replace('|','-'))
s1 = 'alex8123egon1120boss_jin626356'
ret = re.sub('\d+','|',s1)
print(ret)
ret = re.sub('\d+','|',s1,1)
print(ret)
ret = re.subn('\d+','|',s1) # 統(tǒng)計(jì)替換了多少次
print(ret)
- compile 編譯正則規(guī)則
- 將正則表達(dá)式編譯成為一個(gè) 正則表達(dá)式對(duì)象
再次使用的是否不用再編譯,執(zhí)行速度相對(duì)快
- 將正則表達(dá)式編譯成為一個(gè) 正則表達(dá)式對(duì)象
com = re.compile('\d+')
print(com)
ret = com.search('abc1cde2fgh3skhfk')
print(ret.group())
ret = com.findall('abc1cde2fgh3skhfk')
print(ret)
ret = com.finditer('abc1cde2fgh3skhfk')
for i in ret:
print(i.group())
- finditer 節(jié)省空間的方法
ret = re.finditer('\d+','abc1cde2fgh3skhfk')
print(ret)
for i in ret:
print(i.group())
ret = re.finditer('\d', 'ds3sy4784a')
#finditer返回一個(gè)存放匹配結(jié)果的迭代器
print(ret) # <callable_iterator object at 0x10195f940>
print(next(ret).group()) #查看第一個(gè)結(jié)果
print(next(ret).group()) #查看第二個(gè)結(jié)果
print([i.group() for i in ret]) #查看剩余的左右結(jié)果
- 前端
- 分組命名
- 分組約束
- 實(shí)際上對(duì)于前端語言來說 都是把不同樣式的字體放在不同的標(biāo)簽中--->標(biāo)簽語言
<h1>函數(shù)</h1>
<a>函數(shù)</a>
<(.*?)>.*?</(.*?)> #分組約束
pattern = '<(?P<tag>.*?)>.*?</(?P=tag)>'
ret = re.search(pattern,'<h1>函數(shù)</h1>')
print(ret)
if ret:
print(ret.group())
print(ret.group(1))
print(ret.group('tag'))
pattern = r'<(.*?)>.*?</\1>'
ret = re.search(pattern,'<a>函數(shù)</a>')
print(ret)
if ret:
print(ret.group())
print(ret.group(1))
(?:正則表達(dá)式) 表示取消優(yōu)先顯示功能
(?P<組名>正則表達(dá)式) 表示給這個(gè)組起一個(gè)名字
(?P=組名) 表示引用之前組的名字,引用部分匹配到的內(nèi)容必須和之前那個(gè)組中的內(nèi)容一模一樣
re模塊: findall search finditer compile
異常處理
-
異常錯(cuò)誤和語法錯(cuò)誤不同:
- 異常錯(cuò)誤編譯階段沒問題執(zhí)行時(shí)發(fā)生錯(cuò)誤(邏輯錯(cuò)誤)
- 即便是放在try語句中的內(nèi)容拄衰,在遇到報(bào)錯(cuò)之后也會(huì)中斷這段語句的執(zhí)行
- 語法錯(cuò)誤編譯階段就就過不去
- PyCharm多行內(nèi)容報(bào)錯(cuò)-->排錯(cuò)從下往上看
[圖片上傳失敗...(image-287b2a-1537186793503)]
- 異常錯(cuò)誤編譯階段沒問題執(zhí)行時(shí)發(fā)生錯(cuò)誤(邏輯錯(cuò)誤)
如果錯(cuò)誤發(fā)生的條件是可預(yù)知的它褪,我們需要用if進(jìn)行處理:在錯(cuò)誤發(fā)生之前進(jìn)行預(yù)防
如果錯(cuò)誤發(fā)生的條件是不可預(yù)知的,則需要用到try...except:在錯(cuò)誤發(fā)生之后進(jìn)行處理
- as語法
這個(gè)e是異常類的一個(gè)實(shí)例翘悉,如果我們完整地解釋這個(gè)問題茫打,我覺得還是從Python的自定義異常類說起比較好。
假如妖混,我們現(xiàn)在自定義一個(gè)簡(jiǎn)單的異常類:
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
我們拋這個(gè)異常的時(shí)候可以這么寫:
try:
raise MyError(2*2)
except MyError as e:
print 'My exception occurred, value:', e.value
我們?cè)诓东@這個(gè)異常之后假如需要訪問TA的一些屬性怎么辦老赤,這個(gè)時(shí)候就可以使用as關(guān)鍵字
所以,這里的e是前面MyError類的一個(gè)instance制市,我們可以直接訪問他的value抬旺,也就是你看到的e.value
- 單分支
#基本語法為
try:
被檢測(cè)的代碼塊
except 異常類型:
try中一旦檢測(cè)到異常,就執(zhí)行這個(gè)位置的邏輯
- 萬能異常
# 萬能異常Exception
s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)
- 多分支 --> 也可以在多分支后來一個(gè)Exception
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
- 合并多分支
try:
num = int(input('num : '))
print(l[num - 1])
except (ValueError,IndexError):
print('輸入了錯(cuò)誤的內(nèi)容')
-
多分支異常與萬能異常
- 如果你想要的效果是祥楣,無論出現(xiàn)什么異常开财,我們統(tǒng)一丟棄汉柒,或者使用同一段代碼邏輯去處理他們,那么騷年责鳍,大膽的去做吧竭翠,只有一個(gè)Exception就足夠了。
- 如果你想要的效果是薇搁,對(duì)于不同的異常我們需要定制不同的處理邏輯,那就需要用到多分支了渡八。
-
else
- 匯報(bào)這段代碼順利的執(zhí)行了 : 發(fā)短信通知啃洋,記錄到文件中
- try/except/else
-
finally
- try/finally
- try/ except / finally
- try/ except / else / finally
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
except Exception as e:
print(e)
else:
print('try內(nèi)代碼塊沒有異常則執(zhí)行我')
finally:
print('無論異常與否,都會(huì)執(zhí)行該模塊,通常是進(jìn)行清理工作')
try/except
try/except/else
try/finally
try/ except / finally
try/ except / else / finally
- 自定義異常
class EvaException(BaseException): #BaseException 相當(dāng)于類的object
def __init__(self,msg):
super().__init__()
self.msg = msg
def __str__(self):
return self.msg
raise EvaException('eva的異常')
- raise 主動(dòng)觸發(fā)異常,拋出/引發(fā)異常 (寫框架寫程序員用到)
- assert 斷言:assert 條件 (寫框架寫程序員用到
assert 1 == 1 #條件為真執(zhí)行
print('*'*100)
assert 1 == 2 #條件為假,報(bào)錯(cuò)
print('*'*100)
- assert 簡(jiǎn)化了raise語句:
需要注意的是,assert語句一般用于開發(fā)時(shí)對(duì)程序條件的驗(yàn)證屎鳍,只有當(dāng)內(nèi)置debug為True時(shí)宏娄,assert語句才有效。當(dāng)Python腳本以-O選項(xiàng)編譯成為字節(jié)碼文件時(shí)逮壁,assert語句將被移除孵坚。
但與raise語句不同的是,assert語句是在條件測(cè)試為假時(shí)窥淆,才引發(fā)異常卖宠。assert語言的一般形式如下:
assert<條件測(cè)試>,<異常附加數(shù)據(jù)>#其中異常附加數(shù)據(jù)是可選的
常用異常
AttributeError 試圖訪問一個(gè)對(duì)象沒有的樹形,比如foo.x忧饭,但是foo沒有屬性x
IOError 輸入/輸出異常扛伍;基本上是無法打開文件
ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯(cuò)誤
IndentationError 語法錯(cuò)誤(的子類) 词裤;代碼沒有正確對(duì)齊
IndexError 下標(biāo)索引超出序列邊界刺洒,比如當(dāng)x只有三個(gè)元素,卻試圖訪問x[5]
KeyError 試圖訪問字典里不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個(gè)還未被賦予對(duì)象的變量
SyntaxError Python代碼非法吼砂,代碼不能編譯(個(gè)人認(rèn)為這是語法錯(cuò)誤逆航,寫錯(cuò)了)
TypeError 傳入對(duì)象類型與要求的不符合
UnboundLocalError 試圖訪問一個(gè)還未被設(shè)置的局部變量,基本上是由于另有一個(gè)同名的全局變量渔肩,
導(dǎo)致你以為正在訪問它
ValueError 傳入一個(gè)調(diào)用者不期望的值因俐,即使值的類型是正確的
- 更多異常
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError