在爬蟲的學習過程當中,又一個你必需要掌握的知識點就是正則表達式python
爬蟲程序須要爬取你須要的東西,那麼就對爬取的結果進行篩選,正則表達式就起到這樣的做用正則表達式
若是你學過任何一門語言,相信你都會接觸正則表達式。而且正則表達式大多相同。函數
無論怎樣,就像開頭說的那樣,由於這是爬蟲基礎教程。因此這篇文章要詳細的說一下python的學習
正則表達式。開始進入正題吧。spa
正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一個字符串是否與某種模式匹配。Python 自1.5版本起增長了re 模塊,它提供 Perl 風格的正則表達式模式。code
re 模塊使 Python 語言擁有所有的正則表達式功能。對象
compile 函數根據一個模式字符串和可選的標誌參數生成一個正則表達式對象。該對象擁有一系列方法用於正則表達式匹配和替換。教程
re 模塊也提供了與這些方法功能徹底一致的函數,這些函數使用一個模式字符串作爲它們的第一個參數。three
首先第一步,看正則表達式模式字符串
模式字符串使用特殊的語法來表示一個正則表達式:
字母和數字表示他們自身,一個正則表達式模式中的字母和數字匹配一樣的字符串。下面說一些模式
1.1
^ --匹配字符串的開頭,在多行模式中匹配每一行的開頭
實例:
import re value = "hello python" value_last = re.match(r'^hello',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 5), match='hello'>
若是換成這樣呢:
import re value = "hello python" value_last = re.match(r'^python',value) print(value_last)
輸出的結果是:
None
1.2
$ --匹配字符串的末尾,在多行模式中匹配每一行的結尾
這個和1.1的用法相同這裏再也不舉例
1.3
. --匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則能夠匹配包括換行符的任意字符
怎麼用?看實例:
import re value = "hello python" value_last = re.match(r'^.ello',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 5), match='hello'>
你也能夠這樣:
import re value = "hello python" value_last = re.match(r'^.ello.......',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 12), match='hello python'>
好調皮的說。
1.4
\ --轉義字符,使後一個字符改變原來的意思
什麼意思呢?好比1.3的"."原本表示匹配任意一個字符,可是若是加上"\"則表示匹配的就是小數點"."
若是仍然聽不懂那麼看例子:
首先嚐試在1.3的例子上把.前面加上\
import re value = "hello python" value_last = re.match(r'^\.ello',value) print(value_last)
輸出的結果是:
None
可是若是是這樣,咱們修改一下value的值
value = ".hello"
這時候你須要去匹配".",怎麼匹配呢?也許你會說用"."可是若是是"*"呢?
value = re.match(r'^\..ello',value)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 6), match='.hello'>
我但願你是瞭解上一個表達式的。
1.5
[...] --字符集,對應的位置能夠是字符集中任意字符。字符集中的字符能夠逐個列出,也能夠給出範圍
,如[abc]或者[a-c],若是第一個字符是^表示取反,如[^abc]表示不是abc的其它字符
,全部特殊字符在字符集中都失去其原有含義。表示一組字符,單獨列出:[abc]匹配'a','b','c'。
import re value = "hello" value_last = re.match(r'^h.[a-z][^abce]',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 4), match='hell'>
1.6
* --匹配前一個字符0或者無限次
就是這個意思:
import re value = "heo" value_last = re.match(r'hel*o',value) print(value_last)
你看,雖然表達式沒有l可是我沒在乎加了l可是不能夠刪除,俺麼我只好用*以前說了能夠匹配前一個字符0次
那麼我要這樣寫
value = 'value_last = re.match(r'hel*o',value)'
value_last = re.match(r'hel*o',value)
結果你應該也能想到吧,沒錯:<_sre.SRE_Match object; span=(0, 11), match='hellllllllo'>
1.7
+ --匹配前一個字符1次或者無限次,就是比*大一咯,不用舉例了吧
1.8
? --匹配前一個字符0次或者一次,這個也不用多說了
1.9
{m} --匹配前一個字符m次
1.11
{m,n} --匹配前一個字符m到n次以上幾個不用多說吧!若是不懂那你就從頭學起吧!
1.12
a|b --匹配a或者b
import re value = "hellllllllo" value_last = re.match(r'h|e',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 1), match='h'>
1.13
(...) --匹配括號內的表達式,也表示一個組
看到1.12的例子,你會不會問,若是在1.12的基礎撒謊那個,像匹配he怎麼辦,固然python會幫你解決這個問題
import re value = "heeho" value_last = re.match(r'(h|e){2,}',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 4), match='heeh'>
1.14
(?:re) --相似(...)可是不表示一個組
1.15
再繼續說特殊構造以前,先要說一下正則表達式的修飾符 - 可選標誌
正則表達式能夠包含一些可選標誌修飾符來控制匹配的模式,修飾符被指定爲一個可選標誌,多個標誌能夠經過
按位OR(|)它們來指定,如re.I|re.M,被設置成I,M標誌:
re.I--使匹配對大小寫不敏感
re.L--使本地化識別(locale-aware)匹配
re.M--多行匹配,影響^和$
re.S--使"."匹配包括換行在內的全部字符
re.U--根據Unicode字符集解析字符,這個標誌影響\w,\W,\b,\B
re.X--該標誌經過給予你更加靈活的格式以便你將正則表達式寫的更易於理解。
1.16
說完了可選標誌,讓咱們繼續往下學習
(?imx) --正則表達式包含三種可選標誌:i,m,x。隻影響括號中的區域
看一個實例:
import re value = "Hello" value_last = re.match(r'(?i)hello',value) print(value_last)
輸出的結果是:
<_sre.SRE_Match object; span=(0, 5), match='hello'>
1.17
(?#...) --將後面的內容看成註釋忽視掉
1.18
(?=...) --以後的字符串內容須要匹配表達式才能成功匹配。
看具體例子:
import re value = "Hello" value_last = re.match(r'(?i)h(?=[a-b])',value) print(value_last)
這種狀況下,因爲h後面的"e"不是在a-b範圍內,所以以後的字符串內容不匹配表達式,這樣
儘管(?i)h匹配H,仍是不能匹配。
所以輸出的結果是:None
import re value = "Hello" value_last = re.match(r'(?i)h(?=[a-z])',value) print(value_last)
這種狀況下,"e"屬於a-z,匹配表達式,所以輸出的結果是:H
1.19
(?!...) --以後的字符串須要不匹配表達式才能成功
1.20
(?<=...) --以前的字符串須要匹配表達式才能成功
1.21
(?<!...) --以前的字符串須要不匹配表達式才能成功
1.22
看完上面的1.1到1.21相信正則表達式的匹配模式你已經掌握差很少了。再來看一些簡單的匹配模式
\d --匹配數字,等價於[0-9]
\D --匹配非數字,等價於[^\d]
\s --匹配空白字符,等價於[\t\r\n\f\v]
\S --匹配非空白字符,等價於[^\s]
\w --匹配單詞字符,等價於[A-Za-z0-9]
\W --匹配非單詞字符,等價於[^\w]
\A --匹配字符串開始
\Z --匹配字符串結束,若是存在換行,只匹配到換行前的結束字符串
\z --匹配字符串結束
\G --匹配最後匹配完成的位置
\b --匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 能夠匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B --匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, --匹配一個換行符。匹配一個製表符。等
\1...\9 --匹配第n個分組的子表達式。
好了,說完了python中的匹配模式,下面該介紹python正則表達式中經常使用的函數了
1.1
首先第一個函數就是剛剛在實例中一直用到的
re.match() --嘗試從字符串的開始匹配一個模式
語法:re.match(pattern,string,flags=0)
pattern是要匹配的正則表達式,string是要匹配的字符串,flags標誌位,用於控制正則表達式的匹配方式
若是匹配成功的話返回一個匹配的對象,不然返回None
能夠用group(num)或者groups()匹配對象函數來獲取匹配表達式
group(num = 0)匹配整個表達式的字符串,group()能夠一次輸入多個組號,這種輕狀況下,它將返回一個包含哪些組所對應值的元組
groups()返回一個包含全部小組字符串的元組,從1到所含的小組號
import re value = "hello world,2015!" value_last = re.match(r'(^[a-z]*)\s(\w*),(\d*.)',value) if value_last: print(value_last.group()) print(value_last.group(1)) print(value_last.group(2)) print(value_last.group(3))
輸出的結果是:
hello world,2015!
hello
world
2015!
1.2
re.search() --會在字符串內查找模式匹配,直到找到第一個匹配
re.search(pattern.string,flags = 0)
與match相同。
二者的區別在於:
re.match只匹配字符串的開始,若是字符串開始不負責正則表達式,則匹配失敗,函數返回None,
可是re.search()匹配整個字符串,直到找到一個匹配
import re value = "hello world,2015!" value_last = re.match(r'2015',value) if value_last: print('match-->',value_last.group()) else: print("No match!") value_end = re.search(r'2015',value) print('search-->',value_end.group())
輸出的結果是:
No match!
search--> 2015
1.3
sub(pattern,repl,string,max=0)
替換字符串的匹配項
import re phone = "2015-5-31 # This is my Num" num = re.sub(r'#.*$',"",phone) print("Phone Num:",num) num = re.sub(r'\D',"",phone) print("Phone Num:",num)
輸出的結果是:
Phone Num: 2015-5-31
Phone Num: 2015531
1.4
split(pattern,string[,maxsplit])
按照可以匹配的字串將string分割後返回列表,maxsplit指定最大分割次數
import re value = "1.one2.two3.three" value_last = re.split(r'\d.',value) print(value_last)
輸出的結果是:
['', 'one', 'two', 'three']
1.5
findall(pattern.string[,flags])
搜索string,以列表形式返回所有能匹配的子串
import re value = "1.one2.two3.three" value_last = re.findall(r'\d.',value) print(value_last)
返回的結果是:
['1.', '2.', '3.']
1.6
finditer(pattern,string[,flags])
返回一個能順序訪問的迭代器
import re value = "1.one2.two3.three" value_last = re.finditer(r'\d.',value) for x in value_last: print(x.group())
返回的結果是:
1.
2.
3.
若是你對迭代器不瞭解的話請翻閱我以前的博客。
正則表達式的就到這邊,正則表達式須要本身常常聯繫,有了這三篇的基礎
set(),deque,正則表達式,下一篇咱們就能詳細的介紹怎麼去寫爬蟲程序了。
鍾志遠 江蘇南京 904727147