摘要:為了逮住某個(gè)目標(biāo),你可能要寫一條長長的,看到自己都頭暈的正則表達(dá)式,看上去就像亂碼一樣。屁,學(xué)正則還不是遲早的事模塊自帶模塊,直接導(dǎo)入即可。匹配規(guī)則規(guī)則其實(shí)是一個(gè)原字符串如表達(dá)式表達(dá)式,較正式的叫法是模式字符串。
如果把BeautifulSopu比喻成通過線索一步步接近目標(biāo)的偵探的話,那么正則表達(dá)式就是牛逼哄哄的“天眼系統(tǒng)”,只要提供一些目標(biāo)的特征,無論搜索范圍多大,只要存在那么一兩個(gè)符合特征的目標(biāo),全都會(huì)被它直接逮住。
特性 牛逼王BS的爸爸,我告訴你個(gè)秘密,其實(shí)BeautifulSoup也是用正則實(shí)現(xiàn)的,而且它find_all的參數(shù)里還能接收正則呢
信息精確定位,BeautifulSoup用的是節(jié)點(diǎn)定位,可能會(huì)出現(xiàn)多個(gè)符合條件的節(jié)點(diǎn)(卻沒有目標(biāo)信息);正則是直接針對(duì)目標(biāo)信息,以字符為單位匹配,一次篩選出正確結(jié)果(前提是寫好正則)
能獲取信息的部分,有時(shí)候完整的信息不是你想要的,你只想取它的某一部分,正則能搞定,BS只能先獲取完整信息再分離。
用途大著呢,不要以為正則只能爬蟲,前后端都少不了正則,你填個(gè)信息判斷是否合法這都是正則,總之學(xué)到賺到啊
勸退大王+這么強(qiáng)大的方法是不是看到都心動(dòng)了,不過強(qiáng)大是有代價(jià)的,較難上手很難精通這兩根大棒一下子錘走了不少初學(xué)者。當(dāng)時(shí)學(xué)的我是這樣的:
抽象&可讀性差。為了逮住某個(gè)目標(biāo),你可能要寫一條長長的,看到自己都頭暈的正則表達(dá)式,看上去就像亂碼一樣。舉個(gè)栗子,如果你要匹配一個(gè)ip地址,正則表達(dá)式會(huì)是這樣
匹配ip地址:((?:(?:25[0-5]|2[0-4]d|[01]?d?d).){3}(?:25[0-5]|2[0-4]d|[01]?d?d)) ——真·亂碼
編寫時(shí)出錯(cuò)率高,新手很難一次寫對(duì),需要不停地修改幾次十幾次才能pass(大腦在顫抖)
難于優(yōu)化,優(yōu)化好的正則能提高匹配速度,然而你這新手還想優(yōu)化,能匹配對(duì)就很不錯(cuò)了(正則暗中偷笑)
如果有足夠的自信和毅力不被正則擊倒,那就來吧。(屁,學(xué)正則還不是遲早的事!)
re 模塊python 自帶模塊,直接導(dǎo)入即可。有匹配,替換等方法。
思考了許久后筆者覺得還是先講表達(dá)式(規(guī)則)好,因?yàn)槟承┓椒ǖ睦斫馐且私獗磉_(dá)式的。
下文的規(guī)則是完全版的,花了很久寫成,分享給讀者,順便當(dāng)成自己的網(wǎng)上筆記。
如果你學(xué)正則只是單單用來爬蟲的話,你只要熟悉“字符匹配”,“分組&或&轉(zhuǎn)義”,“預(yù)定字符集”,“數(shù)量詞”,“非貪婪模式”和(?:)取消分組,了解(或干脆不學(xué))“邊界匹配”,“特殊構(gòu)造”就行了。
如果你覺得正則是你未來工作的剛需的話,推薦熟悉所有規(guī)則。
匹配規(guī)則(pattern)規(guī)則其實(shí)是一個(gè)原字符串如r"表達(dá)式"/r"表達(dá)式",較正式的叫法是模式字符串。最后再說一句,匹配以單個(gè)字符為單位(除括號(hào)能把多個(gè)字符打包成分組(整體)來匹配)
表達(dá)式本質(zhì)是字符串,不要單引(雙引)號(hào)里套單引(雙引)號(hào),會(huì)出錯(cuò)。
任一字符(空格也算)——就是匹配這個(gè)字符,某些字符因?yàn)樵谡齽t中有特殊用途需前加反斜杠轉(zhuǎn)義如 [ { . | ( ) ^ * + ? $
.——英文句號(hào),匹配除換行符 外的任意單個(gè)字符
[]——匹配中括號(hào)里的任一字符,與-結(jié)合還能表示范圍內(nèi)的任一字符,中括號(hào)內(nèi)的字符除外會(huì)自動(dòng)轉(zhuǎn)義,還有小心多個(gè)中括號(hào)嵌套錯(cuò)誤
[^]——中括號(hào)最前面加^,與[ ]反義,匹配一個(gè)不在中括號(hào)里的字符,也可以用橫杠-
r"[abcd]"#匹配一個(gè)a或b或c或d r"[0-9]"#匹配一個(gè)0至9的數(shù),-的作用域是左右各一個(gè)字符 r"[a-z]" r"[A-Z]"#分別匹配a到z或A到Z的一個(gè)字母 r"[12-89]"#注意因?yàn)槭菃巫址ヅ?匹配的是1,2到8的數(shù),9(即1到9的一個(gè)數(shù)),不是12到89的數(shù) r"[{.|()^*+?$]"#匹配 { . | ( ) ^ * + ? $ 中任一個(gè),要轉(zhuǎn)義 r"[^a-zA-Z]"#匹配一個(gè)不是字母的字符分組&或&轉(zhuǎn)義
()——括號(hào),表達(dá)式分組(第n組,n=1,2,3....99,從左往右數(shù)),并形成子表達(dá)式
(?P
(?P=name)——引用分配過名字的分組,但沒有分組功能
|——或,左右規(guī)則任意匹配一個(gè),從左往右嘗試匹配,一旦成功就跳過后面的規(guī)則。|沒被包在括號(hào)中間的話它的作用域是整個(gè)表達(dá)式,被包的話作用域在括號(hào)內(nèi)
——反斜杠,后接功能字有符轉(zhuǎn)義功能,后接數(shù)字(1到99)有引用分組的功能,后接某些字母又有特殊功能
r"abc|def|ghi"#匹配abc或def或ghi r"ma(?:k|d)e"#匹配make或made r"(abc)def1"#相當(dāng)于r"(abc)defabc",匹配abcdefabc r"(?P預(yù)定字符集abc)f(?P=ok)"#為(abc)子組分配了“ok”的名字,然后再引用,匹配abcfabc
d——匹配任一個(gè)數(shù)字(0~9)
D——匹配一個(gè)非數(shù)字字符,與d互補(bǔ)
s——匹配一個(gè)空白字符,包括空格, , , , ,f,v
S——匹配一個(gè)非空白字符
w——匹配一個(gè)單詞字符。unicode下匹配各種語言的單個(gè)字符,單個(gè)數(shù)字,和下橫線。ASCII下匹配單個(gè)英文字母,單個(gè)數(shù)字,和下橫線
W——匹配一個(gè)非單詞字符
r"w" #能匹配"物語&ものがたり"中的:物,語,も,の,が,た,り,漢語日語的單字,其他語言同理數(shù)量詞(接在字符或子組后)
{n}——作用于前一個(gè)字符或子表達(dá)式,匹配它重復(fù)n次
{min,max}——作用于前一個(gè)字符或子表達(dá)式,匹配它重復(fù)重復(fù)多少次min~max次,min和max可只寫一個(gè)設(shè)置重復(fù)下限或上限,但逗號(hào)不能省,不寫min時(shí)min默認(rèn)為0
*——星號(hào),作用于前一個(gè)字符或子表達(dá)式,匹配它零次或多次
+——作用于前一個(gè)字符或子表達(dá)式,匹配它至少一次
?——作用于前一個(gè)字符或子表達(dá)式,匹配它零次或一次
r"z{3}"#匹配zzz r"z{0,3}"#匹配z或zz或zzz r"(?:abc){2}"#對(duì)子表達(dá)式匹配兩次,匹配abcabc,(?:)是一個(gè)用法,不分組的意思,詳看后面 #星號(hào)加號(hào)問號(hào)同理非貪婪模式
在數(shù)量詞后接?,對(duì)前面的數(shù)量詞開啟非貪婪模式,意思就是在能匹配的前提下盡可能少的重復(fù)匹配。
正則默認(rèn)開啟貪婪模式
r"<.+>"#默認(rèn)貪婪,對(duì)于"邊界匹配"能匹配到" "整條,因?yàn)?貪婪地把尖括號(hào)也匹配掉了 r"<.+?>"#非貪婪,對(duì)于" "能匹配到" "和" "
^——放在表達(dá)式的最前面,作用域是表達(dá)式,在多行模式中,在每一行匹配字符串開頭(多行模式要手動(dòng)開啟,否則和A沒什么區(qū)別)
$——放在表達(dá)式的最后面,作用域是表達(dá)式,在多行模式中,在每一行匹配字符串末尾(多行模式要手動(dòng)開啟,否則和沒什么區(qū)別)
A——放在表達(dá)式的最前面,作用域是表達(dá)式,匹配字符串開頭,不能多行匹配
——放在表達(dá)式的最后面,作用域是表達(dá)式,匹配字符串末尾,不能多行匹配
——不匹配字符,只匹配一個(gè)邊界,匹配w和W或W和w的邊界(單詞字符和非單詞字符的邊界)
B——不匹配字符,只匹配一個(gè)邊界,與相反,匹配w和w或W和W的邊界
r"^abc|^def"#匹配abc開頭或def開頭,開啟了多行模式時(shí),對(duì)字符串"abcd defh"能匹配出abc,def兩個(gè) r"abc$|def$"#匹配abc結(jié)尾或def結(jié)尾,開啟了多行模式時(shí),對(duì)字符串"0abc 0def"能匹配出abc,def兩個(gè) r"Aabc"#匹配abc開頭,因?yàn)椴荒芏嘈衅ヅ洌退汩_啟多行模式,對(duì)字符串"abcd abcd"只能匹配到前面的abc #同理 r"wW"#匹配“單詞字符+非單詞字符”的結(jié)構(gòu)如"a!","1%" #B同理特殊構(gòu)造(不作為分組,不被findall捕獲)
(?:)——取消括號(hào)的分組功能,使其不會(huì)被findall方法捕獲
(?#)——#后寫注釋內(nèi)容,整個(gè)(?#)會(huì)被忽略
A(?=)——A之后的字符串需要匹配括號(hào)里的表達(dá)式A才會(huì)被匹配,一定用在表達(dá)式的最后(A是表達(dá)式,(?=)內(nèi)的表達(dá)式不會(huì)被匹配捕捉,下同)
A(?!)——A之后的字符串需要不匹配括號(hào)里的表達(dá)式A才會(huì)被匹配,一定用在表達(dá)式的最后
(?<=)A——A之前的字符串需要匹配括號(hào)里的表達(dá)式A才會(huì)被匹配,一定用在表達(dá)式的最前,括號(hào)內(nèi)的表達(dá)式需固定長度不能使用除{n}外的數(shù)量詞
(?——A之前的字符串需要不匹配括號(hào)里的表達(dá)式A才會(huì)被匹配,一定用在表達(dá)式的最前,括號(hào)內(nèi)的表達(dá)式需固定長度不能使用除{n}外的數(shù)量詞
r"(ab(?=cde))"#匹配后面是bcd的ab r"a(?!d+)"#匹配后面不跟一串?dāng)?shù)字的a,后括號(hào)可用所有數(shù)量詞 r"(?<=abc)de"#匹配前面是abc的de r"(?(?iLmsux)——放在表達(dá)式最前面,為所在的表達(dá)式設(shè)置模式,”i”, “L”, “m”, “s”, “u”, “x”,它們不匹配任何字串,對(duì)應(yīng)python中re模塊當(dāng)中的(re.I, re.L, re.M, re.S, re.U, re.X)的6種模式,下面flag參數(shù)講
r"(?i)abc"#“i”對(duì)應(yīng)re.I,忽略大小寫模式,能匹配Abc,ABC,abc等方法&參數(shù)相比于繁雜的規(guī)則,方法則要簡單多了,常用的就這幾個(gè):
re.search(pattern,string,flags=0),返回第一個(gè)匹配的match對(duì)象(內(nèi)含匹配字符串的信息)
re.findall(pattern,string,flags=0),返回所有匹配分組的字符串組成的列表,沒設(shè)置分組相當(dāng)于整個(gè)表達(dá)式就是一個(gè)分組
#如果表達(dá)式有多個(gè)分組,會(huì)返回復(fù)雜的列表,因此findall中的表達(dá)式通常只有一個(gè)分組
re.finditer(pattern,string,flags=0),同findall功能,但是返回的是迭代器
re.findall(r"d+(abc)d+","1abc1,2abc2")#分組為(abc),findall只捕捉被數(shù)字包起來的abc返回列表["abc","abc"] re.findall(r"((?:ab){2}d)d","abab11,abab22")#整個(gè)表達(dá)式匹配abab加一個(gè)兩位數(shù),(?:)取消了ab的分組,findall只捕捉abab加一個(gè)數(shù),返回列表["abab1","abab2"]pattern = re.compile(pattern,flags=0),把規(guī)則打包返回(如多次使用該規(guī)則),相當(dāng)與pattern和flag的合體,當(dāng)成pattern使用可免去設(shè)置flags
re.sub(pattern,repl,string,count=0,flags)把匹配到的部分用指定字符串repl替換,count設(shè)置替換次數(shù),默認(rèn)為零替換所有
參數(shù):
pattern:接收模式字符串,即表達(dá)式,也可以接收打包的規(guī)則
string:接收待匹配字符串,如html文檔
flags:模式(標(biāo)簽),接受以下模式,多個(gè)模式用“|”分開如 flags=re.I|re.M
re.I = re.IGNORECASE ? 忽略大小寫
re.L = re.LOCALE ? 支持當(dāng)前語言,為了支持多語言版本的字符集使用環(huán)境
re.U = re.UNICODE ? 使用w,W,b,B這些元字符時(shí)將按照UNICODE定義的屬性
re.M = re.MULTILINE ? 開啟多行模式
re.S = re.DOTALL ? 使.能匹配換行符
re.X = re.VERBOSE ? 可以忽略正則表達(dá)式中的空白和#號(hào)的注釋,不匹配空格和#注釋
re.A ?開啟ASCII模式
match對(duì)象方法列出常用方法,下面的match是對(duì)象
match.group(id/name)id是分組序號(hào)(1~99),name是分組的自定名字,返回指定分組的字符串;不傳參數(shù)數(shù)是返回整條匹配字符串
match.start(id/name),match.end(id/name),match.span(id/name),分別返回指定分組字符串在整個(gè)字符串中的開始位置,結(jié)束位置,范圍。
地獄之旅到這就結(jié)束了,不僅是讀者的,還是我的,お疲れ
文章過長,可能存在某些瑕疵和錯(cuò)誤,歡迎提出
累成茍,最近而且要忙于學(xué)習(xí),又被P大學(xué)事件惡心了一下,接下來的產(chǎn)能會(huì)下降,估計(jì)一個(gè)星期多一點(diǎn)更一次
正則慢慢學(xué)就行,正則的使用后面會(huì)有實(shí)例讓大家熟悉
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/41584.html
摘要:大奉打更人賣報(bào)小郎君這個(gè)人仙太過正經(jīng)言歸正傳從紅月開始黑山老鬼穩(wěn)住別浪跳舞二解析數(shù)據(jù)是一個(gè)可以從或文件中提取數(shù)據(jù)的庫。 目錄 一、XPath解析數(shù)據(jù) 1、XPath解析數(shù)據(jù) 2、XML的樹形結(jié)構(gòu) 3、使用XPath選取節(jié)點(diǎn) 4、課堂案例 - 爬取起點(diǎn)小說網(wǎng) 二、BeautifulSoup解析...
摘要:能看到這里說明快進(jìn)入動(dòng)態(tài)網(wǎng)頁爬取了,在這之前還有一兩個(gè)知識(shí)點(diǎn)要了解,就如本文要講的及其數(shù)據(jù)提取是什么是輕量級(jí)的文本數(shù)據(jù)交換格式,符合的格式的字符串叫字符串,其格式就像中字符串化后的字典,有時(shí)字典中還雜著列表字典,但是里面的數(shù)據(jù)都被雙引號(hào)包著 ??能看到這里說明快進(jìn)入動(dòng)態(tài)網(wǎng)頁爬取了,在這之前還有一兩個(gè)知識(shí)點(diǎn)要了解,就如本文要講的json及其數(shù)據(jù)提取 JSON 是什么 ??json是輕量級(jí)...
摘要:下面跟大家詳細(xì)分享一下寫爬蟲抓取靜態(tài)網(wǎng)站的全過程。而我們上面說的元字符都代表一定的規(guī)則和占據(jù)一定的字符。 遇到的需求 前段時(shí)間需要快速做個(gè)靜態(tài)展示頁面,要求是響應(yīng)式和較美觀。由于時(shí)間較短,自己動(dòng)手寫的話也有點(diǎn)麻煩,所以就打算上網(wǎng)找現(xiàn)成的。 中途找到了幾個(gè)頁面發(fā)現(xiàn)不錯(cuò),然后就開始思考怎么把頁面給下載下來。 由于之前還沒有了解過爬蟲,自然也就沒有想到可以用爬蟲來抓取網(wǎng)頁內(nèi)容。所以我采取的辦...
摘要:今天就專門看看正則表達(dá)式。下面是一個(gè)正則表達(dá)式最簡單的使用例子。這個(gè)例子使用了正則表達(dá)式模塊的函數(shù),它會(huì)返回所有符合模式的列表。查詢標(biāo)志讓正則表達(dá)式具有不同的行為。,按給定正則表達(dá)式分割字符串。,正則表達(dá)式中捕獲組的數(shù)量。 最近研究Python爬蟲,很多地方用到了正則表達(dá)式,但是沒好好研究,每次都得現(xiàn)查文檔。今天就專門看看Python正則表達(dá)式。本文參考了官方文檔 re模塊。 模式 首...
閱讀 3401·2021-10-08 10:15
閱讀 5441·2021-09-23 11:56
閱讀 1467·2019-08-30 15:55
閱讀 445·2019-08-29 16:05
閱讀 2725·2019-08-29 12:34
閱讀 2036·2019-08-29 12:18
閱讀 914·2019-08-26 12:02
閱讀 1650·2019-08-26 12:00