聚沙成塔--爬蟲系列(三)(正則表達式)

版權(quán)聲明:本文為作者原創(chuàng)文章,可以隨意轉(zhuǎn)載亏拉,但必須在明確位置表明出處?垓摺D嫖 及塘!

為什么要學(xué)習(xí)正則表達式

處理文本和數(shù)據(jù)是件大事,也是我們?nèi)粘9ぷ髦姓急容^多的一部分锐极,文字處理笙僚、網(wǎng)頁填表、來自數(shù)據(jù)庫的信息流灵再、股票報價信息肋层、新聞列表等等。但是因為我們可能不知道這些需要計算機編程處理文本或數(shù)據(jù)的具體內(nèi)容翎迁,所有把這些文本或數(shù)據(jù)以某種被計算機識別和處理的模式表達出來是非常有用的栋猖,而正則表達式(高級文本模式匹配)可以通過一些字符和特殊符號組合成能被計算機識別的模式在文本數(shù)據(jù)中去匹配我們定義的字符串集合。python的爬蟲是離不開正則表達式的汪榔,如果正則表達式學(xué)不好蒲拉,那么爬蟲肯定是學(xué)不好的,爬蟲學(xué)不好怎么去爬妹子的信息痴腌,怎么去給女朋友提高工作效率雌团,怎么去搶票...

正則表達式使用的特殊符號和字符

記號 說明 舉例
literal 匹配字符串的值 foo
re1 匹配正則表達re1或re2 foo|bar
. 匹配任何字符串(除換行符外) b.b
^ 匹配字符串的開始 ^Dear
$ 匹配字符串結(jié)尾 /bin/*sh$
* 匹配前面出現(xiàn)的正則表達式零次或多次 [A-Za-z0-9]*
+ 匹配前面出現(xiàn)的正則表達式一次或多次 [a-z]+.com
匹配前面出現(xiàn)的正則表達式零次或一次 goo?
{N} 匹配前面出現(xiàn)的正則表達式N次 [0-9]{3}
{M, N} 匹配重復(fù)出現(xiàn)M次到N次的正則表達式 [0-9]{5, 9}
[...] 匹配字符組里出現(xiàn)的任意一個字符 [aeiou]
[..x-y..] 匹配從字符x到y(tǒng)中的任意一個字符 [0-9],[A-Za-z]
[^...] 不匹配此字符集中出現(xiàn)的任何一個字符士聪,包括某一范圍的字符(如果在次字符集中出現(xiàn)) [^aeiou],^[A-Za-z0-9]
(*|+*?|{})? 用于上面出現(xiàn)的任何“非貪婪”版本重復(fù)匹配次數(shù)符號(*,+,?,{}) .*?[a-z]
(...) 匹配封閉括號中的正則表達式锦援,并保存為子組 ([0-9]{3})?, f(oo|u)bar
特殊字符
\d 匹配任何數(shù)字,和[0-9]一樣(\D:匹配任何非數(shù)字字符) data\d+.txt
\w 匹配任何數(shù)字字母字符剥悟,和[A-Za-z0-9]一樣(\W是\w的反義) [A-Za-z_]\w+
\s 匹配任何空白符灵寺,和[\n\t\r\v\f]相同(\S是\s的反義) of\sthe
\b 匹配單詞邊界(\B是\b的反義) \bThe\b
\nn 匹配已保存的子組 price:\16
\c 逐一匹配特殊字符c(既曼库,取消它的特殊含義,按字面匹配) .,\,*
\A, \Z 匹配字符串的起始和結(jié)束 \ADear, \ZDear

python的正則表達式模塊re模塊

re模塊主要的函數(shù)和方法如下:

  • compile(pattern, flags=0)
    對正則表達式模式pattern進行編譯替久,flags可選標(biāo)志凉泄,具體的可選標(biāo)志可以查看api文檔,通常情況下使用re.S(除換行符外匹配所有字符)函數(shù)返回一個regex對象
  • match(pattern, string, flags=0)
    在字符串string中匹配表達式模式pattern, 如果成功匹配則返回一個匹配對象蚯根,否則返回None
  • search(pattern, string, flags=0)
    在字符串string中查找正則表達式模式pattern的第一次出現(xiàn)后众,flags可選標(biāo)志,如果成功匹配則返回一個匹配對象颅拦,否則返回None
  • findall(pattern, string[,flags])
    在字符串string中查找正則表達式pattern的所有(非重復(fù))出現(xiàn)蒂誉,返回一個匹配對象的列表
  • finditer(pattern, string[,flags])
    和findall()相同,但返回的不是列表而是迭代器距帅;對于每個匹配右锨,該迭代器返回一個匹配對象
  • split(pattern, string, max=0)
    根據(jù)正則表達式pattern 中的分隔符把字符string 分割為一個列表,返回成功匹配的列表碌秸,最多分割max 次(默認是分割所有匹配的地方)绍移。
  • sub(pattern, repl, string, max=0)
    把字符串string 中所有匹配正則表達式pattern 的地方替換成字符串repl,如果max 的值沒有給出,則對所有匹配的地方進行替換
  • group(num=0)
    返回全部匹配對象(或指定編號是num 的子組)
  • groups()
    返回一個包含全部匹配的子組的元組(如果沒有成功匹配讥电,就返回一個空元組)

實戰(zhàn)

  • 記號literal使用
import re

content = '''Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or
the code—we would be grateful if you could report this to us. By doing so, you can
save other readers from frustration and help us improve subsequent versions of this
book. If you find any errata, please report them by visiting http://www.packtpub.
com/submit-errata,'''

# literal 匹配字符串的值
pattern = re.compile('find', re.S)

# 使用findall函數(shù)蹂窖,該函數(shù)返回一個列表
items = re.findall(pattern, content)
print('findall() 返回一個列表: %s' % items)
print('*'*100)
# 使用finditer函數(shù),該函數(shù)返回一個迭代器,迭代器是一個match對象恩敌,需要用match對象的group()函數(shù)取值
items = re.finditer(pattern, content)
print('finditer()返回一個迭代器:%s' % items)
for index, item in enumerate(items):
    print('item[%d] = %s, item-value = %s' % (index, item, item.group()))
print('*'*100)

# 使用match函數(shù), 該函數(shù)返回一個match對象, 該函數(shù)只返回一個匹配的對象瞬测,切記!切記纠炮!
# 這個函數(shù)只檢查正則表達式是不是在string的開始位置匹配,所以下面的表達式返回的是None
items = re.match(pattern, content)
print(items)
print('*'*100)

# 使用search, 該函數(shù)返回表達式模式pattern的第一次出現(xiàn), 同時該函數(shù)返回一個match對象
item = re.search(pattern, content)
print('item = %s, item-value = %s' % (item, item.group()))
print('*'*100)

# sub替換字符串中pattern匹配的地方, 下面是將字符串中的find替換成hello
item = re.sub(pattern, 'hello', content)
print(item)
print('*'*100)

pattern = re.compile('find|we', re.S)
# 使用findall函數(shù)月趟,該函數(shù)返回一個列表
items = re.findall(pattern, content)
print('findall() 返回一個列表: %s' % items)
print('*'*100)

執(zhí)行結(jié)果

findall() 返回一個列表: ['find', 'find']
****************************************************************************************************
finditer()返回一個迭代器:<callable_iterator object at 0x000001464B11AE80>
item[0] = <_sre.SRE_Match object; span=(100, 104), match='find'>, item-value = find
item[1] = <_sre.SRE_Match object; span=(346, 350), match='find'>, item-value = find
****************************************************************************************************
None
****************************************************************************************************
item = <_sre.SRE_Match object; span=(100, 104), match='find'>, item-value = find
****************************************************************************************************
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you hello a mistake in one of our books—maybe a mistake in the text or
the code—we would be grateful if you could report this to us. By doing so, you can
save other readers from frustration and help us improve subsequent versions of this
book. If you hello any errata, please report them by visiting http://www.packtpub.
com/submit-errata,
****************************************************************************************************

正則表達是的綜合運用

# |表示或的意思,x|y|z|...表示匹配x或y或z或者其它
pattern = re.compile(r'find|we', re.S)
# 使用findall函數(shù)恢口,該函數(shù)返回一個列表
items = re.findall(pattern, content)
print('findall() 返回一個列表: %s' % items)
print('*'*100)

# .匹配任何字符除換行符外, 
pattern = re.compile(r'f..d', re.S) #匹配f,d之間包含兩個任意字符的字符串結(jié)果
items = re.findall(pattern, content)
print(items)
print('*'*100)

# ^匹配字符串的開始
pattern = re.compile(r'^Although', re.S) # 匹配以Although開始的字符串
items= re.findall(pattern, content)
print(items)
print('*'*100)

# $匹配字符串結(jié)尾
pattern = re.compile(r'submit-errata,$', re.S)
items= re.findall(pattern, content)
print(items)
print('*'*100)

# 匹配以字符串Although孝宗,并且以字符串submit-errata,結(jié)尾的字符串
pattern = re.compile(r'^Although.*?submit-errata,$', re.S)
items= re.findall(pattern, content)
print(items)
print('*'*100)

# split() 分割字符串
pattern = re.compile(r' ', re.S)
items= re.split(pattern, content)
print(items)
print('*'*100)

# \b匹配單詞邊界 \bAlthough表示匹配以單詞Although開頭的字符串,Although\b表示以Although的單詞
pattern = re.compile(r'\bAlthough\b', re.S) #精確匹配單詞Although
items= re.findall(pattern, content)
print(items)
print('*'*100)

# 查找字符串中的url
pattern = re.compile(r'\w{3}\.\w+\.\w{3}', re.S) #精確匹配單詞Although
items= re.findall(pattern, content)
print(items)
print('*'*100)

# 查找字符串中的url
pattern = re.compile(r'[a-zA-z]+://[^\s]*', re.S) #精確匹配單詞Although
items= re.findall(pattern, content)
print(items)
print('*'*100)

執(zhí)行結(jié)果

****************************************************************************************************
findall() 返回一個列表: ['we', 'find', 'we', 'find']
****************************************************************************************************
['find', 'find']
****************************************************************************************************
['Although']
****************************************************************************************************
['submit-errata,']
****************************************************************************************************
['Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or\nthe code—we would be grateful if you could report this to us. By doing so, you can\nsave other readers from frustration and help us improve subsequent versions of this\nbook. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata,']
****************************************************************************************************
['Although', 'we', 'have', 'taken', 'every', 'care', 'to', 'ensure', 'the', 'accuracy', 'of', 'our', 'content,', 'mistakes', 'do', 'happen.', 'If', 'you', 'find', 'a', 'mistake', 'in', 'one', 'of', 'our', 'books—maybe', 'a', 'mistake', 'in', 'the', 'text', 'or\nthe', 'code—we', 'would', 'be', 'grateful', 'if', 'you', 'could', 'report', 'this', 'to', 'us.', 'By', 'doing', 'so,', 'you', 'can\nsave', 'other', 'readers', 'from', 'frustration', 'and', 'help', 'us', 'improve', 'subsequent', 'versions', 'of', 'this\nbook.', 'If', 'you', 'find', 'any', 'errata,', 'please', 'report', 'them', 'by', 'visiting', 'http://www.packtpub.com/submit-errata,']
****************************************************************************************************
['Although']
****************************************************************************************************
['www.packtpub.com']
****************************************************************************************************
['http://www.packtpub.com/submit-errata,']
****************************************************************************************************

note:不管是學(xué)習(xí)爬蟲還是運用到其它文本處理方面正則表達是都是我們不得不學(xué)習(xí)的東西耕肩,正則表達是需要多用因妇,長時間不用很快就會忘記,還有最重要的一點如果你正在讀這篇文章請記得一定要自己去實踐看疗,只有實踐你才回發(fā)現(xiàn)問題沙峻。正則表達式?jīng)]有通用的表達式,只有適合的表達式两芳,一種匹配可已有不同的正則表達式摔寨,正所謂不管是白貓還是黑貓,只要能抓到老鼠都是好貓怖辆。

更多的文章可以關(guān)注我的blog:http://www.gavinxyj.com


歡迎關(guān)注我的公眾號:愛做飯的老謝是复,老謝一直在努力...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末删顶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子淑廊,更是在濱河造成了極大的恐慌逗余,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件季惩,死亡現(xiàn)場離奇詭異录粱,居然都是意外死亡,警方通過查閱死者的電腦和手機画拾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門啥繁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人青抛,你說我怎么就攤上這事旗闽。” “怎么了蜜另?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵适室,是天一觀的道長。 經(jīng)常有香客問我举瑰,道長捣辆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任嘶居,我火速辦了婚禮罪帖,結(jié)果婚禮上促煮,老公的妹妹穿的比我還像新娘邮屁。我一直安慰自己,他們只是感情好菠齿,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布佑吝。 她就那樣靜靜地躺著,像睡著了一般绳匀。 火紅的嫁衣襯著肌膚如雪芋忿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天疾棵,我揣著相機與錄音戈钢,去河邊找鬼。 笑死是尔,一個胖子當(dāng)著我的面吹牛殉了,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拟枚,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼薪铜,長吁一口氣:“原來是場噩夢啊……” “哼众弓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起隔箍,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤谓娃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜒滩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滨达,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年俯艰,在試婚紗的時候發(fā)現(xiàn)自己被綠了弦悉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟆炊,死狀恐怖稽莉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涩搓,我是刑警寧澤污秆,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站昧甘,受9級特大地震影響良拼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜充边,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一庸推、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浇冰,春花似錦贬媒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至漂佩,卻和暖如春脖含,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背投蝉。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工养葵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘩缆。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓关拒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子夏醉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

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