前言
re是python的一個正則匹配庫,可以使用正則表達式匹配出我們想要的內容
findall 使用
findall 看下源碼介紹, 返回字符串中所有不重疊匹配項的列表。
findall匹配的時候,會把結果放到list返回,如果沒有匹配到返回空list不會報錯
- pattern 匹配的正則表達式
- string 待匹配的字符串
- flags=0 標志位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。
def findall(pattern, string, flags=0):
"""Return a list of all non-overlapping matches in the string.
If one or more capturing groups are present in the pattern, return
a list of groups; this will be a list of tuples if the pattern
has more than one group.
Empty matches are included in the result."""
return _compile(pattern, flags).findall(string)
3種使用形式
import re
kk = re.compile(r'\d+') # 匹配數字
res1 = kk.findall('one1two2three3four4')
print(res1)
# ['1', '2', '3', '4']
# 注意此處findall()的用法,可傳兩個參數;
kk = re.compile(r'\d+')
res2 = re.findall(kk,"one123two2")
print(res2)
# ['123', '2']
# 也可以直接在findall傳2個參數
res3 = re.findall(r'\d+', "one123two2")
print(res3)
# ['123', '2']
findall 示例
匹配多個滿足條件的結果,找出字符串中有多少個ab, 兩個字符挨着的
a = "abcaabffabbcdaccbfabbbgggaaabbbkk"
# 1.找出字符串中有多少個ab, 兩個字符挨着
res1 = re.findall(r"ab", a)
print(res1)
# ['ab', 'ab', 'ab', 'ab', 'ab']
繼續查找如ab, aab, aaab,aaaab這種,a可以重復,也就是匹配前面的a是1個或多個
+是代表前面的字符出現1次或多次
import re
a = "abcaabffabbcdaccbfabbbgggaaabbbkk"
# 2.+是代表前面的字符出現1次或多次
res1 = re.findall(r"a+b", a)
print(res1)
# ['ab', 'aab', 'ab', 'ab', 'aaab']
*是代表匹配前面的字符出現0次或多次
import re
a = "abcaabffabbcdaccbfabbbgggaaabbbkk"
# 3.*代表前面的字符出現0次或多次
res1 = re.findall(r"a*b", a)
print(res1)
# ['ab', 'aab', 'ab', 'b', 'b', 'ab', 'b', 'b', 'aaab', 'b', 'b']
我們要匹配a和b之間有一個字符的,比如aab,abb,acb,adb都符合
.就是匹配除 \n (換行符)以外的任意一個字符
import re
a = "abcaabffabbcdaccbfabbbgggaaabbbkk"
# .就是匹配除 \n (換行符)以外的任意一個字符
res1 = re.findall(r"a.b", a)
print(res1)
# ['aab', 'abb', 'abb', 'aab']
貪婪 與 非貪婪
接着繼續查找a和b之間,可以有字符如axb,axxxb,axxxxb ,其中x是任意字符,x也可以沒有字符如ab。
但中間不能包含b,遇到b立馬結束,如abcaab這種不符合,遇到第一個b就結束匹配
符號.* 貪婪,匹配從.*前面為開始到后面為結束的所有內容
import re
a = "abcaabffabbcdaccbfabbbgggaaabbbkk"
# 符號.* 貪婪,匹配從.*前面為開始到后面為結束的所有內容
res1 = re.findall(r"a.*b", a)
print(res1)
# ['abcaabffabbcdaccbfabbbgggaaabbb']
符號.*? 非貪婪,遇到開始和結束就進行截取,因此截取多次符合的結果,中間沒有字符也會被截取
import re
a = "abcaabffabbcdaccbfabbbgggaaabbbkk"
# 符號.*? 非貪婪,遇到開始和結束就進行截取
res1 = re.findall(r"a.*?b", a)
print(res1)
# ['ab', 'aab', 'ab', 'accb', 'ab', 'aaab']
()的使用
比如我要從下面這段文本中取出我的博客地址, 上面學到的.*?是非貪婪匹配,可以匹配出我們想要的內容
import re
a = "作者-上海悠悠 QQ交流群:717225969 blog地址:https://www.cnblogs.com/yoyoketang/ 歡迎收藏"
res1 = re.findall(r'blog地址:.*? 歡迎收藏', a)
print(res1)
# ['blog地址:https://www.cnblogs.com/yoyoketang/ 歡迎收藏']
如果不加括號,它會把匹配的一整串全部取出來,其實我們只想要中間的那段內容,於是可以用(.*?)
import re
a = "作者-上海悠悠 QQ交流群:717225969 blog地址:https://www.cnblogs.com/yoyoketang/ 歡迎收藏"
res1 = re.findall(r'blog地址:(.*?) 歡迎收藏', a)
print(res1)
# ['https://www.cnblogs.com/yoyoketang/']
re.S匹配換行
前面匹配都是一整串沒有換行的情況,如果我們需要匹配的內容,中間剛好有換行了,那就匹配不到了。
.就是匹配除 \n (換行符)以外的任意一個字符,這里是不包含換行的
import re
a = '''作者-上海悠悠 QQ交流群:717225969 blog地址:https:
//www.cnblogs.com/yoyoketang/ 歡迎收藏
'''
# 中間有換行的時候匹配
res1 = re.findall(r'blog地址:(.*?) 歡迎收藏', a)
print(res1)
# []
前面介紹findall源碼的時候還有個flags參數,這個時候就可以派上用處了,加上flags=re.S參數,忽略換行符
import re
a = '''作者-上海悠悠 QQ交流群:717225969 blog地址:https:
//www.cnblogs.com/yoyoketang/ 歡迎收藏
'''
# 中間有換行的時候匹配
res1 = re.findall(r'blog地址:(.*?) 歡迎收藏', a, flags=re.S)
print(res1)
# ['https:\n//www.cnblogs.com/yoyoketang/']
正則表達式修飾符
正則表達式可以包含一些可選標志修飾符來控制匹配的模式。修飾符被指定為一個可選的標志。
修飾符 | 描述 |
---|---|
re.I | 使匹配對大小寫不敏感 |
re.L | 做本地化識別(locale-aware)匹配 |
re.M | 多行匹配,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內的所有字符 |
re.U | 根據Unicode字符集解析字符。這個標志影響 \w, \W, \b, \B. |
re.X | 該標志通過給予你更靈活的格式以便你將正則表達式寫得更易於理解。 |
多個標志可以通過按位 OR(|) 它們來指定。如 re.I | re.M 被設置成 I 和 M 標志