Python數(shù)據(jù)分析與挖掘之正則表達(dá)式詳解

什么是正則表達(dá)式

世界上信息非常多,而我們關(guān)注的信息有限。假如我們希望只提取出關(guān)
注的數(shù)據(jù),此時(shí)可以通過(guò)一些表達(dá)式進(jìn)行提取,正則表達(dá)式就是其中一
種進(jìn)行數(shù)據(jù)篩選的表達(dá)式。

原子

原子是正則表達(dá)式中最基本的組成單位,每個(gè)正則表達(dá)式中至少要包含
一個(gè)原子。常見(jiàn)的原子類(lèi)型有:

  • a普通字符作為原子
  • b非打印字符作為原子
  • c通用字符作為原子
  • d原子表

正則表達(dá)式函數(shù)

正則表達(dá)式函數(shù)有re.match()函數(shù)、re.search()函數(shù)、全局匹配函數(shù)、 re.sub()函數(shù)。

re.search

re.search 掃描整個(gè)字符串并返回第一個(gè)成功的匹配。

import re

pat = "yue"
string = "http://iqianyue.com"
result = re.search(pat,string)
print(result)

輸出結(jié)果如下:

<_sre.SRE_Match object; span=(12, 15), match='yue'>

re.match

re.match 嘗試從字符串的起始位置匹配一個(gè)模式,如果不是起始位置匹配成功的話(huà),match()就返回none。

import re

pat = "yue"
string = "yuehttp://iqyueianyue.com"
result = re.match(pat,string)
print(result)

輸出結(jié)果如下:

<_sre.SRE_Match object; span=(0, 3), match='yue'>

全局匹配函數(shù) re.compile().findall():

掃描整個(gè)字符串并以列表的形式返回符合條件的匹配值

import re 

pat = "p.*?n"
string = "abcpythonjgkhappynn"
result = re.compile(pat).findall(string)
print(result)

輸出結(jié)果如下:

['python', 'ppyn']

re.match與re.search的區(qū)別

re.match只匹配字符串的開(kāi)始,如果字符串開(kāi)始不符合正則表達(dá)式,則匹配失敗,函數(shù)返回None;而re.search匹配整個(gè)字符串,直到找到一個(gè)匹配。

模式修正符

所謂模式修正符,即可以在不改變正則表達(dá)式的情況下,通過(guò)模式修正符改變正則表達(dá)式的含義,從而實(shí)現(xiàn)一些匹配結(jié)果的調(diào)整等功能。
正則表達(dá)式中常用的模式修正符有i、g、m、s、x、e等。它們之間可以組合搭配使用。

  • 修正符:i不區(qū)分大小寫(xiě)的匹配;
  • 修正符:m將字符串視為多行,不管是那行都能匹配;
  • 修正符:s將字符串視為單行,換行符作為普通字符;
  • 修正符:x將模式中的空白忽略;
  • 修正符:A強(qiáng)制從目標(biāo)字符串開(kāi)頭匹配;
  • 修正符:D如果使用$限制結(jié)尾字符,則不允許結(jié)尾有換行;
  • 修正符:U只匹配最近的一個(gè)字符串;不重復(fù)匹配;

舉例如下:

import re

pat = "bai"
string = "http://www.Baidu.com"
result = re.search(pat,string,re.I)#不區(qū)分大小寫(xiě)
print(result)

貪婪模式與懶惰模式

貪婪模式的核心點(diǎn)就是盡可能多的匹配,而懶惰模式的核心點(diǎn)就是盡可能少的匹配(更精確的定位)。

import re

pat1 = "p.*y"#貪婪模式(盡可能多的匹配)
pat2 = "p.*?y"#懶惰模式(盡可能少的匹配)
string = "abcpythonfghappy"
result1 = re.search(pat1,string)
result2 = re.search(pat2,string)
print(result1)
print(result2)

輸出結(jié)果如下:

<_sre.SRE_Match object; span=(3, 16), match='pythonfghappy'>
<_sre.SRE_Match object; span=(3, 5), match='py'>

正則表達(dá)式實(shí)例

實(shí)例 描述
python 匹配 "python"
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括號(hào)內(nèi)的任意一個(gè)字母
[0-9] 匹配任何數(shù)字。類(lèi)似于 [0123456789]
[a-z] 匹配任何小寫(xiě)字母
[A-Z] 匹配任何大寫(xiě)字母
[a-zA-Z0-9] 匹配任何字母及數(shù)字
[^aeiou] 除了aeiou字母以外的所有字符
. 匹配除 "\n" 之外的任何單個(gè)字符。要匹配包括 '\n' 在內(nèi)的任何字符,請(qǐng)使用象 '[.\n]' 的模式。
\d 匹配一個(gè)數(shù)字字符。等價(jià)于 [0-9]。
\D 匹配一個(gè)非數(shù)字字符。等價(jià)于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、換頁(yè)符等等。等價(jià)于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等價(jià)于 [^ \f\n\r\t\v]。
\w 匹配包括下劃線的任何單詞字符。等價(jià)于'[A-Za-z0-9_]'。
\W 匹配任何非單詞字符。等價(jià)于 '[^A-Za-z0-9_]'。

非打印字符

元字符 描述
\cx 匹配由x指明的控制字符。例如, \cM 匹配一個(gè) Control-M 或回車(chē)符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個(gè)原義的 'c' 字符。
\f 匹配一個(gè)換頁(yè)符。等價(jià)于 \x0c 和 \cL。
\n 匹配一個(gè)換行符。等價(jià)于 \x0a 和 \cJ。
\r 匹配一個(gè)回車(chē)符。等價(jià)于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、換頁(yè)符等等。等價(jià)于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等價(jià)于 [^ \f\n\r\t\v]。
\t 匹配一個(gè)制表符。等價(jià)于 \x09 和 \cI。
\v 匹配一個(gè)垂直制表符。等價(jià)于 \x0b 和 \cK。

特殊字符

特別字符 描述
$ 匹配輸入字符串的結(jié)尾位置。如果設(shè)置了 RegExp 對(duì)象的 Multiline 屬性,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,請(qǐng)使用 $。
( ) 標(biāo)記一個(gè)子表達(dá)式的開(kāi)始和結(jié)束位置。子表達(dá)式可以獲取供以后使用。要匹配這些字符,請(qǐng)使用 \( 和 \)。
* 匹配前面的子表達(dá)式零次或多次。要匹配 * 字符,請(qǐng)使用 \*。
+ 匹配前面的子表達(dá)式一次或多次。要匹配 + 字符,請(qǐng)使用 \+。
. 匹配除換行符 \n 之外的任何單字符。要匹配 . ,請(qǐng)使用 \. 。
[ 標(biāo)記一個(gè)中括號(hào)表達(dá)式的開(kāi)始。要匹配 [,請(qǐng)使用 \[。
? 匹配前面的子表達(dá)式零次或一次,或指明一個(gè)非貪婪限定符。要匹配 ? 字符,請(qǐng)使用 \?。
\ 將下一個(gè)字符標(biāo)記為或特殊字符、或原義字符、或向后引用、或八進(jìn)制轉(zhuǎn)義符。例如, 'n' 匹配字符 'n'。'\n' 匹配換行符。序列 '\' 匹配 "",而 '(' 則匹配 "("。
^ 匹配輸入字符串的開(kāi)始位置,除非在方括號(hào)表達(dá)式中使用,此時(shí)它表示不接受該字符集合。要匹配 ^ 字符本身,請(qǐng)使用 \^。
{ 標(biāo)記限定符表達(dá)式的開(kāi)始。要匹配 {,請(qǐng)使用 \{。
指明兩項(xiàng)之間的一個(gè)選擇。

限定符

字符 描述
* 匹配前面的子表達(dá)式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價(jià)于{0,}。
+ 匹配前面的子表達(dá)式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價(jià)于 {1,}。
? 匹配前面的子表達(dá)式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價(jià)于 {0,1}。
{n} n 是一個(gè)非負(fù)整數(shù)。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個(gè) o。
{n,} n 是一個(gè)非負(fù)整數(shù)。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價(jià)于 'o+'。'o{0,}' 則等價(jià)于 'o*'。
{n,m} m 和 n 均為非負(fù)整數(shù),其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個(gè) o。'o{0,1}' 等價(jià)于 'o?'。請(qǐng)注意在逗號(hào)和兩個(gè)數(shù)之間不能有空格。

python中正則表達(dá)式常用場(chǎng)景

  • 匹配.com或.cn網(wǎng)址
import re 

pat = "[a-zA-Z]+://[^\s]+[.com|.cn]"
string = '<a 
result = re.compile(pat).findall(string)
print(result)

輸出如下:

['http://www.baidu.com']
  • 匹配JavaScript帶標(biāo)簽的網(wǎng)址

比如從 https://read.douban.com/provider/all中將所有出版社提取出來(lái),把無(wú)關(guān)信息過(guò)濾掉。<div class="name">北京師范大學(xué)出版社</div>

import urllib
import re

# <div class="name">北京師范大學(xué)出版社</div>
url = "https://read.douban.com/provider/all"
pat = '<div class="name">(.*?)</div>'
data = urllib.request.urlopen(url).read().decode("utf-8","ignore")
result = re.compile(pat).findall(data)
print(result)

輸出結(jié)果如下:

['博集天卷', '北京郵電大學(xué)出版社', '北京師范大學(xué)出版社', '百花洲文藝出版社', '百花文藝出版社', '長(zhǎng)江數(shù)字', '重慶大學(xué)出版社', '東方文萃', '讀客圖書(shū)', '電子工業(yè)出版社', '當(dāng)代中國(guó)出版社', '第一財(cái)經(jīng)周刊', '豆瓣閱讀同文館', '豆瓣', '豆瓣閱讀', '豆瓣閱讀出版計(jì)劃', '東方巴別塔文化', '鳳凰壹力', '鳳凰悅世泓文', '鳳凰聯(lián)動(dòng)', 'Fiberead', '復(fù)旦大學(xué)出版社', '鳳凰雪漫', '果殼閱讀', '果麥文化', '廣西師范大學(xué)出版社', '杭州藍(lán)獅子文化創(chuàng)意股份有限公司', '后浪出版公司', '華東師范大學(xué)出版社', '華章數(shù)媒', '漢唐陽(yáng)光', '華文時(shí)代', '湖北人民出版社', '華章同人', '華夏盛軒', '海豚出版社', '虹膜出版', '化學(xué)工業(yè)出版社', '華中科技大學(xué)出版社', '湖北科學(xué)技術(shù)出版社', '黑龍江北方文藝出版社', '華文經(jīng)典', 'HarperCollins', '聚石文華', '金城出版社', '簡(jiǎn)書(shū)', '今古傳奇', '江蘇人民出版社', '九州幻想', '科幻世界', '酷威文化', '理想國(guó)', '漓江出版社', '磨鐵數(shù)盟', '寧波出版社', '南方人物周刊', 'ONE·一個(gè)', '浦睿文化', 'Parkstone International', 'Packt Publishing', '清華大學(xué)出版社', '青島出版社', '《人物》雜志', '人民文學(xué)出版社', '人民郵電出版社', '儒意欣欣', '人民東方出版?zhèn)髅?, '人民文學(xué)雜志社', '上海九久讀書(shū)人', '世紀(jì)文景', '四川數(shù)字出版?zhèn)髅接邢薰?, '上海譯文出版社', '時(shí)代華文', '上海雅眾文化', '世紀(jì)文睿', '時(shí)代華語(yǔ)', '商務(wù)印書(shū)館', '生活·讀書(shū)·新知三聯(lián)書(shū)店', '上海社會(huì)科學(xué)院出版社', '社會(huì)科學(xué)文獻(xiàn)出版社', '山西春秋電子音像出版社', '時(shí)代數(shù)聯(lián)', '陜西人民出版北京分公司', '《書(shū)城》雜志', '世圖北京', '四川文藝出版社', '上海文藝出版社', '上海人民出版社', '上海交通大學(xué)出版社', '斯坦威圖書(shū)', '上海人民美術(shù)出版社', '圖靈社區(qū)', 'Trajectory', '武漢大學(xué)出版社北京分社', '萬(wàn)有圖書(shū)', '我和豆瓣', '新經(jīng)典文化電子書(shū)', '新星出版社', '新華先鋒文化傳媒', '雪球', '懸疑世界', '現(xiàn)代出版社', '西南財(cái)經(jīng)大學(xué)出版社', '新華出版社', '新華先鋒出版科技', '譯林出版社', '譯言·東西文庫(kù)', '譯言·古登堡計(jì)劃', '悅讀紀(jì)', '陽(yáng)光博客', '悅讀名品', '燕山出版社', '閱文集團(tuán)華文天下', '中信出版社', '中國(guó)人民大學(xué)出版社', '中作華文', '中國(guó)輕工業(yè)出版社', '紫圖圖書(shū)', '浙版數(shù)媒', '中央編譯出版社', '知乎', '中國(guó)國(guó)家地理圖書(shū)部', '浙江攝影出版社', '中國(guó)經(jīng)濟(jì)出版社', '中國(guó)青年出版社', '中國(guó)民主法制出版社', '中國(guó)傳媒大學(xué)出版社', '中國(guó)言實(shí)出版社', '浙江大學(xué)出版社', '湛廬文化', '浙江文藝出版社', '中華書(shū)局']
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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