日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

find_all 返回空 python_python小课堂23 - 正则表达式(一)

發(fā)布時(shí)間:2024/9/27 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 find_all 返回空 python_python小课堂23 - 正则表达式(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

python小課堂23 - 正則表達(dá)式(一)

前言

今天來介紹一下Python的正則表達(dá)式。先來看下定義,何為正則表達(dá)式?

正則表達(dá)式是一個(gè)特殊的字符序列,一個(gè)字符串是否與我們給定的這個(gè)字符序列相匹配。正則最重要的功能就是處理字符串,例如檢索你在某一段字符串中的特定單詞,或者將原來某個(gè)位置的特定字符換成你想要的字符。而對(duì)于爬蟲來說,正則表達(dá)式是必不可少的技能之一,要想正確提取源代碼中你想要的信息內(nèi)容,一般來說都會(huì)用到正則。

Python的re模塊初體驗(yàn)

這里用例子來假設(shè)一個(gè)場(chǎng)景吧...現(xiàn)在你正打算轉(zhuǎn)行踏入程序員的領(lǐng)域,然而面臨的第一個(gè)問題就是選擇一個(gè)主修語言來作為你轉(zhuǎn)行后的學(xué)習(xí)動(dòng)力。于是有個(gè)字符串language="Java,Python,Go,Js,C,C++,PHP",你下定決心要學(xué)Python,于是讓你判斷Python這門語言是否在這個(gè)字符串中存在!你會(huì)怎么做呢?

方案一:

通過python內(nèi)置函數(shù)string.index('Python')

language = 'Java,Python,Go,Js,C,C++,PHP' print(language.index('Python'))>>> 5

結(jié)果說明在索引下標(biāo)第5位開始,尋找到了Python字符串。

方案二:

通過in關(guān)鍵詞

language = 'Java,Python,Go,Js,C,C++,PHP' print('Python' in language)>>> True

結(jié)果說明Python字符串存在于language中。

方案三:

通過re模塊,需要import re。

import re language = 'Java,Python,Go,Js,C,C++,PHP' """re.findall(pattern, string, flags=0):必填的兩個(gè)參數(shù):第一個(gè)參數(shù)是正則表達(dá)式的模式;第二個(gè)參數(shù)是原字符串選填參數(shù): flags ,傳入例如忽略大小寫的官方參數(shù)返回的結(jié)果是: list """ result = re.findall('Python',language) print(result)>>> ['Python']

大家可以仔細(xì)看下代碼,注釋已經(jīng)寫得很清楚啦....使用re.findall,見名知意,是查找到所有匹配到的,所以返回的肯定是list。不信的話,我們將代碼修改一下,在language里多加一個(gè)Python,看下結(jié)果如何:

Python正則表達(dá)式的原理性概念

這個(gè)標(biāo)題起的名字有些拗口,因?yàn)槲艺也坏胶玫母爬ㄔ~語了,現(xiàn)在就來解釋一下吧....我們通過re模塊來判斷了一個(gè)字符串包含不包含與原始字符串,實(shí)際上這種用法是沒有意義的,真正的正則表達(dá)式用法場(chǎng)景,應(yīng)該是依賴于規(guī)則!

1.普通字符和元字符

還是舉例說明,還是上邊找工作的那堆語言,假設(shè)每門語言的分割,我不用逗號(hào)進(jìn)行分割了,我將各種公共電話號(hào)碼隨機(jī)插入來代替逗號(hào),于是得到language="Java110Python120Go119Js4399C999C++666PHP"。

需求變更了,現(xiàn)在讓你提取出電話號(hào)碼!如何去做呢?

import re language="Java110Python120Go119Js4399C999C++666PHP" """re.findall(pattern, string, flags=0):必填的兩個(gè)參數(shù):第一個(gè)參數(shù)是正則表達(dá)式的模式;第二個(gè)參數(shù)是原字符串選填參數(shù): flags,傳入例如忽略大小寫的官方參數(shù)返回的結(jié)果是: list """ result = re.findall('d',language) print(result)>>> ['1', '1', '0', '1', '2', '0', '1', '1', '9', '4', '3', '9', '9', '9', '9', '9', '6', '6', '6']

由于每個(gè)數(shù)字都不近相同,你可以用一堆數(shù)字去寫,但是比較麻煩。若換成字符,難不成還寫滿了你要匹配的字符嗎?所以這里提出兩個(gè)概念:普通字符和元字符。

普通字符:re.findall('Python',language)中的'Python',就是普通字符。
元字符:re.findall('d',language)中的'd',就是元字符。

所謂的普通字符,就是你寫死了的固定字符,而元字符則不一樣,它代表的是一類的字符,而我現(xiàn)在寫的'd'的含義就是匹配所有數(shù)字。需要注意的是,普通字符和元字符是在正則表達(dá)式中可以混合使用的!

而我這里不會(huì)詳細(xì)的介紹每個(gè)元字符的用法,重要的是自己查閱相關(guān)文檔的方法,而非死記硬背這些元字符的含義,可以用到的時(shí)候再去查即可。這里給出相關(guān)圖吧,有興趣的可以看下:

以上圖片原址: https://baike.baidu.com/item/正則表達(dá)式/1700215?fr=aladdin#3

具體使用可以自行百度查看。

2. 字符集

在上面的例子中,我們可以看到,正則表達(dá)式匹配完的list得到的都是一個(gè)個(gè)拆分的字符,而所謂的字符集就是匹配出來的字符集合,也就是多個(gè)字符。如下面的例子:

import rewords = "abz,acz,adz,aez,afz" result = re.findall('a[bcd]z', words) print(result)>>> ['abz', 'acz', 'adz']

若想匹配到原字符串中的多個(gè)字符,我們可以用[]這樣的形式來匹配多個(gè)符合的內(nèi)容,而[]中的元素相互之間是或的關(guān)系。a,z來限定邊界, [bcd] 則是匹配a,z中間符合的bcd的元素,所以最終得到的結(jié)果如上。

import rewords = "abz,acz,adz,aez,afz" result = re.findall('a[^bcd]z', words) print(result)>>> ['aez', 'afz']

若在字符集的正則規(guī)定前,加上^則是代表取反的意思,可以看到結(jié)果,不匹配bcd,最終結(jié)果得到的是e,f。

當(dāng)然還有一種寫法是下面這樣:

import rewords = "abz,acz,adz,aez,afz" result = re.findall('a[b-e]z', words) print(result)>>> ['abz', 'acz', 'adz', 'aez']

用 - 也可以來表示一個(gè)范圍,比如A-Z,a-z,0-9等....

3. 數(shù)量詞

import rewords = "I am learning Pythonnnnnn, that 's awesome!" result = re.findall('[a-z]{4}', words) print(result)>>> ['lear', 'ning', 'ytho', 'nnnn', 'that', 'awes']

在字符集的基礎(chǔ)上,我們?nèi)绻胂薅ǘ嗌匍L(zhǎng)度的字符,可以通過{}來限定匹配字符集的長(zhǎng)度,當(dāng)我寫入4的時(shí)候,可以看到從左到右,只有當(dāng)相鄰字符組成的長(zhǎng)度為4時(shí),才會(huì)被匹配到。

然而這樣匹配是沒有實(shí)際意義的,我現(xiàn)在需要的是將每個(gè)詞語拆分并且匹配到,于是有了下面的寫法:

import rewords = "I am learning Pythonnnnnn, that 's awesome!" result = re.findall('[a-zA-Z]{1,11}', words) print(result)>>> ['I', 'am', 'learning', 'Pythonnnnnn', 'that', 's', 'awesome']

{最短匹配長(zhǎng)度,最長(zhǎng)匹配長(zhǎng)度},在配合上字符集的正則寫法,既可拆分出原有的單詞,注意的是[a-zA-Z] 這里用到了組合的寫法,匹配字符是符合大小寫a-z的。

大家有沒有注意到一個(gè)點(diǎn),就是在數(shù)量詞這里,我對(duì)原字符串進(jìn)行正則匹配,取得長(zhǎng)度是1~11位,那么在am時(shí)候就已經(jīng)符合一位長(zhǎng)度了,即字母a,為什么沒有被單獨(dú)匹配出來作為結(jié)果呢?這里就涉及到下面要說的正則表達(dá)式的貪婪模式與非貪婪模式了。

正則表達(dá)式的貪婪與非貪婪模式

貪婪模式:意如其名,貪婪嘛,就是要多多多!多匹配既是王道!

非貪婪模式:與貪婪模式相反唄,即少匹配就是王道!

對(duì)應(yīng)上面的數(shù)量詞案例時(shí),數(shù)量詞若是采用范圍取長(zhǎng)度時(shí),則是默認(rèn)使用貪婪模式,即多多匹配,所以才會(huì)看到能匹配到字符集長(zhǎng)度多的單詞。而Python默認(rèn)傾向于是貪婪模式的!

1. “?” 匹配0次或者1次

在實(shí)際的應(yīng)用中,我們也會(huì)遇到非貪婪的情況,即少匹配,那么如何書寫呢?

import rewords = "I am learning Pythonnnnnn, that 's awesome!" result = re.findall('[a-zA-Z]{1,11}?', words) print(result)>>> ['I', 'a', 'm', 'l', 'e', 'a', 'r', 'n', 'i', 'n', 'g', 'P', 'y', 't', 'h', 'o', 'n', 'n', 'n', 'n', 'n', 'n', 't', 'h', 'a', 't', 's', 'a', 'w', 'e', 's', 'o', 'm', 'e']

只需要在數(shù)量詞后面加一個(gè)?即可。代表的是匹配前面的數(shù)量詞0次或者1次。

特殊的小技巧:?一般可以來去掉字符后面的重復(fù)項(xiàng),例如原字符串:"Pythonnnnn",可以用 'Python?' 得到Python, 這點(diǎn)自己可以思考并實(shí)驗(yàn)下。

2. “*” 匹配0次或者無限次

下面這段代碼,你認(rèn)為會(huì)打印出什么樣的結(jié)果呢?

import re words = "I am learning Pytho,Python,Pythonnnnnn, that 's awesome!" result = re.findall('Pytho*', words) print(result)

輸出結(jié)果:

>>> ['Pytho', 'Pytho', 'Pytho']

因?yàn)樵谠址衅ヅ涞給,后面就截止了。

若是這樣呢:

import re words = "I am learning Pytho,Python,Pythonnnnnn, that 's awesome!" result = re.findall('Python*', words) print(result) #輸出結(jié)果>>> ['Pytho', 'Python', 'Pythonnnnnn']

匹配 * 號(hào)的前一個(gè)字符無限次,所以有多少n,就會(huì)被匹配到多少n。為什么Pytho也能被匹配到呢?因?yàn)?* 號(hào)代表的是前面的字符匹配到0次也是可以的!所以pytho也會(huì)被匹配到,這里需要注意。

3. “+” 匹配1次或者無限次

import rewords = "I am learning Pytho,Python,Pythonnnnnn, that 's awesome!" result = re.findall('Python+', words) print(result)# 輸出結(jié)果 >>> ['Python', 'Pythonnnnnn']

+號(hào)是匹配前面的字符至少一次,或者n次。所以不會(huì)匹配到Pytho!

4. “.” 匹配除換行符n之外的其他所有字符

import rewords = "Python n !@#%%$*&(%)" result = re.findall('.', words) print(result)>>> ['P', 'y', 't', 'h', 'o', 'n', ' ', ' ', '!', '@', '#', '%', '%', '$', '*', '&', '(', '%', ')']

可以看到,除了n以外的字符都匹配到了,包括空格以及其他奇怪的字符~

正則表達(dá)式組的概念

在說組之前,再來介紹一個(gè)正則的用法:

^: 匹配原字符串的首位置開始

$: 匹配原字符串的尾位置結(jié)束

如下事例:

import rewords = "110120119999" result = re.findall('^d{1,9}$', words) print(result)>>> []

因?yàn)閊和$限定了原始字符串的頭和尾,從原始字符串中匹配1~9位長(zhǎng)度的數(shù)字,并且是從頭到尾的去匹配,并沒有長(zhǎng)度為9的數(shù)字,所以匹配出來是空的。

正則表達(dá)式組的概念:還記得之前python的基礎(chǔ)數(shù)據(jù)類型元組嗎?正則中的組,與字符集恰好相反,字符集中匹配的字符之間是或的關(guān)系,而組中匹配的字符之間則是與的關(guān)系。

場(chǎng)景如下,我現(xiàn)在想匹配整個(gè)hungry!!而若是通過字符匹配的話方法:

import rewords = "I'm hungry!!hungry!!hungry!!...." result = re.findall('hungry!!{3}', words) print(result)>>> []

可以看到,什么也沒匹配到,因?yàn)楝F(xiàn)在寫的意思是匹配前面是hungry!!且最后一個(gè)嘆號(hào)長(zhǎng)度為3個(gè),也就是說如果字符串中有hungry!!!!,即可匹配到。

如果想匹配到整個(gè)hungry!!并且連續(xù)的單詞出現(xiàn)3次,就要這么寫啦:

import rewords = "I'm hungry!!hungry!!hungry!!!!...." result = re.findall('(hungry!!){3}', words) print(result)>>> ['hungry!!']

用小括號(hào)將整個(gè)單詞括起來,它就是所謂的分組了。若我要是將{3}改成{4},就會(huì)發(fā)現(xiàn),匹配不到這個(gè)結(jié)果了,因?yàn)樾枰M內(nèi)連續(xù)出現(xiàn)4次才可以匹配到。如下:

總結(jié)

今天主要介紹了python的re模塊的findall方法,此方法是入門正則表達(dá)式一個(gè)比較好的學(xué)習(xí)方式,通過各種實(shí)例可以看到最終匹配到的結(jié)果,而需要注意的點(diǎn)是:普通字符和元字符,元字符相當(dāng)于是系統(tǒng)的寫法,每種寫法代表不同的含義,在使用的時(shí)候可以將二者混合使用來達(dá)到你最終想匹配的值,現(xiàn)在也許看著正則還會(huì)有很多的疑惑,后續(xù)寫到爬蟲的時(shí)候,一講就明白了!

至此完!

有想交流溝通python相關(guān)知識(shí)的同學(xué),歡迎關(guān)注公號(hào): migezatan.(咪哥雜談)

總結(jié)

以上是生活随笔為你收集整理的find_all 返回空 python_python小课堂23 - 正则表达式(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。