
Python是一種在數(shù)據(jù)處理上非常占優(yōu)勢的計算機編程語言,這一篇文章就記錄我在學(xué)習(xí)正則表達式時的經(jīng)驗吧。此處只介紹常用的正則表達式,學(xué)完后一般的正則表達式也都能處理啦。
一、入門
常用正則表達式符號:
^a //以a開頭
. //任意一個字符
* //任意數(shù)量的字符
* //任意字符任意數(shù)量
3$ // 以3結(jié)尾
? //消除貪婪模式
舉個栗子:
line="booooooobby123"
假如想提取line字符串中的booooooob
先定義字符串“規(guī)則”——正則表達式
regex_str=".*(b.*b).*"
引號里面的字符串是什么意思呢?
對照著第一個表,.* 代表字符串的前面是任意數(shù)量的任意字符,
接著是() ,括號內(nèi)匹配到的字符串就是最終提取出來返回到regex_str的字符串,
然后括號里面代表的是b字符+中間任意數(shù)量任意字符+b字符(正好對應(yīng)我們想要提取出來的booooooob)
最后以.*任意數(shù)量的任意字符結(jié)尾
以上的字符串僅僅是個將要匹配到所要字符串的一個模式或者說你你定義的規(guī)則,從其他字符串中要符合你的規(guī)則就能匹配并提出來想要的字符串
接下來進行匹配
match_obj=re.match(regex_str,line)
match_obj得到的就是從line字符串中,滿足regex_str規(guī)則的一個字符串元祖
為什么說是元祖呢,接著往下看
if match_obj:
print(match_obj.group(1))
如果匹配成功則輸出match_obj中g(shù)roup關(guān)鍵字的(1)項,這說明match_obj得到的不僅僅是字符串,而是由很多元素組成的元祖,其中g(shù)roup屬性是個列表元素。
那么group又是什么呢?
其實仔細(xì)思考一下,如果有非常長的字符串,而恰好滿足你所定義規(guī)則的字符串有多個,將會讓所有的字符串加入到group列表中,其中我們?nèi)?1)即可得到第一個匹配到的字符串。
好了,將上述代碼輸入后發(fā)現(xiàn)打印出:
bb
what?
其實這里是正則表達式的一個特性,就是貪婪匹配模式。
那么什么是貪婪匹配模式呢?
- 從右往左匹配
- 貪婪,匹配的字符串越長越好
booooooobby123字符串從左開始匹配,y123匹配到定義規(guī)則里面的.*,然后b匹配到括號里面的b,接著下一個b又匹配到括號內(nèi)的第二個b,好了,括號里面的正則已經(jīng)匹配完成,并且括號后面的.*符合booooooo,所以返回最終返回字符串為括號內(nèi)的bb
那要怎么解決呢?
?+有貪婪模式的字符可以消除貪婪模式,所以這么改:
regex_Str=".*?(b.*b).*"
然后,發(fā)現(xiàn)匹配到的是booooooobb!?。?/p>
崩潰!
看看我上面提到的貪婪匹配特點第二點(貪婪,匹配的字符串越長越好),消除了bb的匹配方式之后,有booooooob和booooooobb可選,當(dāng)然會選擇更長的那個。
改進:
regex_Str=".*?(b.*?b).*"
二、進階
+ //至少出現(xiàn)一次
.+ // 任意字符至少出現(xiàn)一次
{a,b} //至少出現(xiàn)a次,最多出現(xiàn)b次
| //或
[abcd] //abcd中任意一個字符
[0-9] //0到9任意一個(區(qū)間)
[0-9]{9} // 0到9任意一個共出現(xiàn)9次
[^1] //(非1)除了1之外的字符任意一個
[.*] //即字符.(點)和*(星號)本身
\s //空格
\S //非空格
\w //即是[A-Za-z0-9_]任意一個
\W //非\w
[\u4E00- \u9FA5] //任意一個漢字
- 為了加深一下上述的貪婪匹配,再舉個栗子。
如果提取line = "study in 南京大學(xué)"
regex_str = ".*([\u4E00- \u9FA5]+大學(xué))"
提取的是
京大學(xué)(這是一種貪婪模式的匹配,從右到左匹配成功后就不再匹配,所以加上問號)
regex_str = ".*?([\u4E00- \u9FA5]+大學(xué))"
- 最后一個栗子
其中正則表達式的一個重要符號:
\d 數(shù)字
現(xiàn)在匹配下面的字符串,想提取2001
line = "XXX出生于2001年"
regex_str=".*(\d+)年"
提取的字符串為1
因為貪婪模式
所以要想提取2001,則需要
regex_str=".*?(\d+)年"
或者
regex_str=".*(\d{4})年"