正則表達(dá)式和re模塊

正則表達(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ì)快
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ò)誤發(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赖瞒,隨后出現(xiàn)的幾起案子女揭,更是在濱河造成了極大的恐慌,老刑警劉巖栏饮,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吧兔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡袍嬉,警方通過查閱死者的電腦和手機(jī)境蔼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門灶平,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人箍土,你說我怎么就攤上這事逢享。” “怎么了吴藻?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵瞒爬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我沟堡,道長(zhǎng)侧但,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任航罗,我火速辦了婚禮禀横,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘粥血。我一直安慰自己柏锄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布复亏。 她就那樣靜靜地躺著趾娃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜓耻。 梳的紋絲不亂的頭發(fā)上茫舶,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音刹淌,去河邊找鬼饶氏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛有勾,可吹牛的內(nèi)容都是我干的疹启。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蔼卡,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼喊崖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起雇逞,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤荤懂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后塘砸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體节仿,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年掉蔬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了廊宪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矾瘾。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖箭启,靈堂內(nèi)的尸體忽然破棺而出壕翩,到底是詐尸還是另有隱情,我是刑警寧澤傅寡,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布放妈,位于F島的核電站,受9級(jí)特大地震影響荐操,放射性物質(zhì)發(fā)生泄漏大猛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一淀零、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膛壹,春花似錦驾中、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至链方,卻和暖如春持痰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祟蚀。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工工窍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人前酿。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓患雏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親罢维。 傳聞我的和親對(duì)象是個(gè)殘疾皇子淹仑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 該筆記整理自Wesley Chun著,孫波翔肺孵、李斌匀借、李晗譯,人民郵電出版社出版的《Python核心編程》第3版平窘,還...
    hufengreborn閱讀 2,067評(píng)論 0 2
  • 正則表達(dá)式常用匹配規(guī)則: 匹配某個(gè)字符串: 以上便可以在hello中吓肋,匹配出he。 點(diǎn)(.)匹配任意的字符: 但是...
    編程小王子AAA閱讀 543評(píng)論 0 0
  • 1初婆,概述 給定一個(gè)正則表達(dá)式和另一個(gè)字符串蓬坡,我們可以達(dá)到如下的目的: 1猿棉,給定的字符串是否符合正則表達(dá)式的過濾邏輯...
    曉可加油閱讀 435評(píng)論 0 1
  • 一堂課: 《古詩(shī)二首》,一首是《曉出凈慈寺送林子方》屑咳,一首是《絕句》萨赁,第一首讓孩子閉上眼睛想象“接天蓮葉無窮碧,映...
    酒窩窩_xlj閱讀 346評(píng)論 0 1
  • 由于昨天晚上睡得比較晚兆龙,讓孩子睡到自然醒杖爽。起床后哪里也沒有去,在家里也沒有讀書紫皇,僅僅練習(xí)了一會(huì)圍棋慰安,便自己...
    瑤昱閱讀 118評(píng)論 0 0