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