正則表達式是對字符串操作的邏輯公式,在某些情況下通過使用正則表達式我們可以輕易地獲取到我們想要的結(jié)果,下面先學(xué)習(xí)簡單的正則表達式后就開始實戰(zhàn)練習(xí)。
模式 | 概述 | 模式 | 概述 |
---|---|---|---|
. | 匹配任意字符,除了換行符 | s | 匹配空白字符 |
* | 匹配前一個字符 0 次或多次 | S | 匹配任何非空白字符 |
+ | 匹配前一個字符 1 次或多次 | d | 匹配數(shù)字,等價于 [0-9] |
? | 匹配前一個字符 0 次或 1 次 | D | 匹配任何非數(shù)字 |
^ | 匹配字符串開頭 | 匹配一個換行符 | |
$ | 匹配字符串末尾 | w | 匹配字母數(shù)字 |
() | 對正則表達式分組并記住匹配的文本 | W | 匹配非字母數(shù)字 |
[…] | 表示一組字符。例:[amk] 匹配 ‘a(chǎn)’,‘m’或’k’ | [^…] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
以上只是一些基本的正則表達式,想更深入了解可以百度。
基本方法re.match 方法
re.match
嘗試從字符串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。
函數(shù)用法為:
re.match(pattern, string, flags=0)
參數(shù) | 描述 |
---|---|
pattern | 匹配的正則表達式 |
string | 匹配的字符串 |
flags | 標志位,用于控制正則表達式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。 |
flags的選擇如下
修飾符 | 描述 |
---|---|
re.I | 使匹配對大小寫不敏感 |
re.L | 做本地化識別(locale-aware)匹配 |
re.M | 多行匹配,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內(nèi)的所有字符 |
re.U | 根據(jù)Unicode字符集解析字符。這個標志影響 w, W, , B. |
re.X | 該標志通過給予你更靈活的格式以便你將正則表達式寫得更易于理解。 |
舉個例子:
import re
string = 'Big bilibili is a learning website haha'
r = re.match(r'(.*) is (.*?) website', string)
print("匹配的整句話:", r.group(0))
print("匹配的第一個結(jié)果:", r.group(1))
print("匹配的第二個結(jié)果:", r.group(2))
print("匹配的結(jié)果列表:", r.groups())
得到的結(jié)果如下:
匹配的整句話: Big bilibili is a learning website
匹配的第一個結(jié)果: Big bilibili
匹配的第二個結(jié)果: a learning
匹配的結(jié)果列表: (‘Big bilibili’, ‘a(chǎn) learning’)
為什么要在正則表達式前加上r呢?r'(.*) is (.*?) website'
前面的r
意思是raw string,代表純粹的字符串,這樣就不會對引號里面的反斜杠進行特殊處理。因為在正則表達式中有一些類似于
d
的模式,所以模式中的單個反斜杠都要進行轉(zhuǎn)譯。
re.search 方法
re.search
掃描整個字符串并返回第一個成功的匹配。
函數(shù)用法為:
re.search(pattern, string, flags=0)
它和re.match
方法有什么區(qū)別呢?re.match
嘗試從字符串的起始位置匹配一個模式,而re.search
掃描整個字符串并返回第一個成功的匹配。舉個簡單的例子:
import re
string = 'Big 6 bilibili is a learning website haha'
r = re.search(r'd (.*) is (.*?) website', string)
print("匹配的整句話:", r.group(0))
print("匹配的第一個結(jié)果:", r.group(1))
print("匹配的第二個結(jié)果:", r.group(2))
print("匹配的結(jié)果列表:", r.groups())
使用re.search
得到結(jié)果如下:
匹配的整句話: 6 bilibili is a learning website
匹配的第一個結(jié)果: bilibili
匹配的第二個結(jié)果: a learning
匹配的結(jié)果列表: (‘bilibili’, ‘a(chǎn) learning’)
使用re.match
方法
import re
string = 'Big 6 bilibili is a learning website haha'
r = re.match(r'd (.*) is (.*?) website', string)
print(r)
因為字符串開頭不是數(shù)字,故無法匹配,得到結(jié)果為None
。
因此我個人認為match方法用到的地方可能會比較少。
re.findall 方法
在字符串中找到正則表達式所匹配的所有子串,并返回一個列表,如果沒有找到匹配的,則返回空列表。
舉個例子和上面兩種方法做個比較:
import re
r_match = re.match(r'd+', '1234 is the first number, 6666 is the second.')
r_search = re.search(r'd+', 'The first number is 1234, the second number is 6666.')
r_findall = re.findall(r'd+', 'The first number is 1234, the second number is 6666.')
print("r_match:", r_match.group())
print("r_search:", r_search.group())
print("r_findall:", r_findall)
得到的結(jié)果如下:
獲取自己的IP地址r_match: 1234
r_search: 1234
r_findall: [‘1234’, ‘6666’]
下面我們通過查看自己IP的網(wǎng)站來看一下使用正則表達式的優(yōu)越性。
我們使用 http://httpbin.org/get 來查看自己的IP地址。
首先分析網(wǎng)頁。
打碼處為我的電腦現(xiàn)在的IP地址。通過分析網(wǎng)頁可知IP地址在一堆字符中的某一處,這樣使用以前的方法一層一層分析已經(jīng)不行了,所以我們現(xiàn)在使用正則表達式來獲取一下IP地址。
我們定義一下獲取頁面的函數(shù)。
def get_page(url,params=None,headers=None,proxies=None):
response = requests.get(url, headers=headers, params=params, proxies=proxies)
print("解析網(wǎng)址:",response.url)
page = BeautifulSoup(response.text, 'lxml')
print("響應(yīng)狀態(tài)碼:", response.status_code)
return page
然后就可以獲取頁面的源碼了:
url = 'http://httpbin.org/get'
headers = {
'Host': 'httpbin.org',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36'
}
page = get_page(url, headers=headers)
使用
page.text
來看一下結(jié)果(打碼處為IP地址):
然后我們分析一下IP地址的特點:
IP地址為由.
分隔開的四組數(shù)字組成,每組數(shù)字有1-3位數(shù)字,這樣我們便可以定義IP地址的正則表達式r'd{1,3}.d{1,3}.d{1,3}.d{1,3}'
,其中.
匹配字符串中的.
。因此可得獲得IP地址的代碼如下:
ip = re.findall(r'd{1,3}.d{1,3}.d{1,3}.d{1,3}', page.text)
print(ip[0])
這樣便可以得到本機的IP地址了。
爬蟲系列Python爬蟲小白教程(一)—— 靜態(tài)網(wǎng)頁抓取
Python爬蟲小白教程(二)—— 爬取豆瓣評分TOP250電影
Python爬蟲小白教程(三)——使用正則表達式分析網(wǎng)頁
Python爬蟲小白教程(四)—— 反反爬之IP代理池
Python爬蟲小白教程(五)—— 多線程爬蟲
本文摘自 :https://blog.51cto.com/u