正則表達式(二)
re模塊(regex)
python中沒有正則表達式的函數,需要引入內置的re模塊
-
re模塊方法:
- match:從頭開始匹配,只匹配一個結果
- 作用:接收用戶傳遞過來的url進行匹配(web框架用到)
- search:整個字符串進行匹配,只匹配第一個獲得的結果
- findall:匹配整個字符串,返回一個列表對象
- finditer:和findall非常類似,返回一個可迭代的對象,迭代的時候才會創建值
- split:字符串切割
- sub:替換
- 最常用match和findall來查找
- match:從頭開始匹配,只匹配一個結果
-
分組的作用:
- 在匹配得到的結果中獲取局部的值
-
re模塊查找分類(match,search,findall):
- 普通匹配:
- 通過match和search匹配成功返回的對象中,group得到的匹配得到的完整結果
regex = 'H\w+' ret = re.match(regex, origin) print(ret.group()) # Hello print(ret.groups()) # () print(ret.groupdict()) # {}
- 分組匹配:
- 分組來獲取局部的值
- match:從頭開始匹配
origin = 'Hello tom, xxx tom, yyy tom haha 19' regex = '(H)(\w+)' ret = re.match(regex, origin) print(ret.group()) # Hello print(ret.groups()) # ('H', 'ello') print(ret.groupdict()) # {}
origin = 'Hello tom, xxx tom, yyy tom haha 19' regex = '(?P<n1>H)(\w+)' ret = re.match(regex, origin) print(ret.group()) # Hello print(ret.groups()) # ('H', 'ello') print(ret.groupdict()) # {'n1': 'H'}
search:知道了group方法之后,searh方法和match方法是一樣的,match是從頭開始匹配,search是全局匹配
-
findall:返回匹配成功的列表
- 不分組:
regex = 'app\w+' origin = 'i have an apple, i have a pen, apple pen' ret = re.findall(regex, origin) print(ret) # ['apple', 'apple']
- 分組:
- findall會把groups里面的所有東西放到列表里面(分組的作用:獲取局部的東西)
- findall對?P<key>不起作用
- 如果分組嵌套分組,則先取外面的,再取里面的
egex = '(app\w+)' origin = 'i have an apple, i have a pen, apple pen' ret = re.findall(regex, origin) print(ret) # ['apple', 'apple'] regex = '(app)\w+' origin = 'i have an apple, i have a pen, apple pen' ret = re.findall(regex, origin) print(ret) # ['app', 'app'] regex = '(app)(\w+)' origin = 'i have an apple, i have a pen, apple pen' ret = re.findall(regex, origin) print(ret) # [('app', 'le'), ('app', 'le')] regex = '((a)(pp))(\w+)' origin = 'i have an apple, i have a pen, apple pen' ret = re.findall(regex, origin) print(ret) # [('app', 'a', 'pp', 'le'), ('app', 'a', 'pp', 'le')]
-
finditer:只有在迭代的時候才創建對象
- 迭代的對象跟match和search獲得的對象一樣
regex = '((a)(pp))(\w+)' origin = 'i have an apple, i have a pen, apple pen' ret1 = re.search(regex, origin) print('type of search', type(ret1)) # type of search <class '_sre.SRE_Match'> ret2 = re.finditer(regex,origin) for i in ret2: print('type of finditer', type(i)) # type of finditer <class '_sre.SRE_Match'>
- 普通匹配:
-
分組注意事項:
- 分組的是按照你真是寫了多少個組來確定的,如果獲得的值多于寫的組個數,則去最后一個
regex = '(\w)(\w)(\w)(\w)' ret = re.findall(regex, 'tony') print(ret) # [('t', 'o', 'n', 'y')] regex = '(\w){4}' ret = re.findall(regex, 'tony') print(ret) # [y]
- 第一個寫了4個組,每個組一個字符:(\w)(\w)(\w)(\w),所以得到的結果是4個組
- 第二個寫的是1個組,需要匹配4個字符,因為真正寫的只有一個組,所有得到的結果為1個組,理論上每個字符的組都是一樣的,最后的會覆蓋前面的,所以取得的是最后一個
ret = re.findall('\dyhh*', '1yhh2yhh3andyhh4yhh') print(ret) # ['1yhh', '2yhh', '4yhh'] ret = re.findall('(\dyhh)*', '1yhh2yhh3andyhh4yhh') print(ret) # ['2yhh', '', '', '', '', '', '', '', '4yhh', '']
- 匹配時盡量避免正則表達式為空值
-
split:分割
- 無分組分割:分割后不包含自己(分隔符)
- 分組分割:分割后會保留分割符內分組的內容
regex = '\d+' origin = 'ad12ad134a34da' ret = re.split(regex, origin) print(ret) # ['ad', 'ad', 'a', 'da'] regex = '(\d+)' origin = 'ad12ad134a34da' ret = re.split(regex, origin, 1) print(ret) # ['ad', '12', 'ad134a34da']
- 使用場景:計算器獲取最里層的括號同時取出括號
origin = '7+((3+4)*5-(4-9)*5)*4' regex = '\(([^()]+)\)' # 獲取最里層的括號,同時對括號里的數據歸到組里,切割后保留括號內的內容 ret = re.split(regex, origin, maxsplit=1) print(ret) # ['7+(', '3+4', '*5-(4-9)*5)*4']
- 再根據切割后得到的結果是否是長度為3的列表,不斷循環計算其值
while True: ret = re.split(regex, origin, maxsplit=1) if len(ret) == 3: 計算得到括號的值,然后重新組合origin字符串 elif: break同時帶出結果
sub:替換 && subn:替換返回一個元組