爬 (將所有的網站的內容全部爬下來)
取 (去掉對我們沒用處的數據)
處" />
新聞資訊  快訊  焦點  財經  政策  社會
互 聯 網   電商  金融  數據  計算  技巧
生活百科  科技  職場  健康  法律  汽車
手機百科  知識  軟件  修理  測評  微信
軟件技術  應用  系統  圖像  視頻  經驗
硬件技術  知識  技術  測評  選購  維修
網絡技術  硬件  軟件  設置  安全  技術
程序開發  語言  移動  數據  開源  百科
安全防護  資訊  黑客  木馬  病毒  移動
站長技術  搜索  SEO  推廣  媒體  移動
財經百科  股票  知識  理財  財務  金融
教育考試  育兒  小學  高考  考研  留學
您當前的位置:首頁 > IT百科 > 程序開發 > 語言 > Python

Python 正則表達式re模塊

時間:2019-11-22 11:21:31  來源:  作者:

為什么要學正則表達式

實際上爬蟲一共就四個主要步驟:

明確目標 (要知道你準備在哪個范圍或者網站去搜索)
爬 (將所有的網站的內容全部爬下來)
取 (去掉對我們沒用處的數據)
處理數據(按照我們想要的方式存儲和使用)
我們在昨天的案例里實際上省略了第3步,也就是"取"的步驟。因為我們down下了的數據是全部的網頁,這些數據很龐大并且很混亂,大部分的東西使我們不關心的,因此我們需要將之按我們的需要過濾和匹配出來。

那么對于文本的過濾或者規則的匹配,最強大的就是正則表達式,是Python爬蟲世界里必不可少的神兵利器。

什么是正則表達式

正則表達式,又稱規則表達式,通常被用來檢索、替換那些符合某個模式(規則)的文本。

正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個"規則字符串",這個"規則字符串"用來表達對字符串的一種過濾邏輯。

給定一個正則表達式和另一個字符串,我們可以達到如下的目的:

給定的字符串是否符合正則表達式的過濾邏輯(“匹配”);
通過正則表達式,從文本字符串中獲取我們想要的特定部分(“過濾”)。

Python  正則表達式re模塊

 


正則表達式匹配規則

Python  正則表達式re模塊

 

Python 的 re 模塊

在 Python 中,我們可以使用內置的 re 模塊來使用正則表達式。

有一點需要特別注意的是,正則表達式使用 對特殊字符進行轉義,所以如果我們要使用原始字符串,只需加一個 r 前綴,示例:

r'chuanzhiboket.tpython'

re 模塊的一般使用步驟如下:

使用 compile() 函數將正則表達式的字符串形式編譯為一個 Pattern 對象

通過 Pattern 對象提供的一系列方法對文本進行匹配查找,獲得匹配結果,一個 Match 對象。

最后使用 Match 對象提供的屬性和方法獲得信息,根據需要進行其他的操作

compile 函數

compile 函數用于編譯正則表達式,生成一個 Pattern 對象,它的一般使用形式如下:

import re

# 將正則表達式編譯成 Pattern 對象
pattern = re.compile(r'd+')

在上面,我們已將一個正則表達式編譯成 Pattern 對象,接下來,我們就可以利用 pattern 的一系列方法對文本進行匹配查找了。

Pattern 對象的一些常用方法主要有:

match 方法:從起始位置開始查找,一次匹配
search 方法:從任何位置開始查找,一次匹配
findall 方法:全部匹配,返回列表
finditer 方法:全部匹配,返回迭代器
split 方法:分割字符串,返回列表
sub 方法:替換

match 方法

match 方法用于查找字符串的頭部(也可以指定起始位置),它是一次匹配,只要找到了一個匹配的結果就返回,而不是查找所有匹配的結果。它的一般使用形式如下:

match(string[, pos[, endpos]])

其中,string 是待匹配的字符串,pos 和 endpos 是可選參數,指定字符串的起始和終點位置,默認值分別是 0 和 len (字符串長度)。因此,當你不指定 pos 和 endpos 時,match 方法默認匹配字符串的頭部。

當匹配成功時,返回一個 Match 對象,如果沒有匹配上,則返回 None。

>>> import re
>>> pattern = re.compile(r'd+') # 用于匹配至少一個數字

>>> m = pattern.match('one12twothree34four') # 查找頭部,沒有匹配
>>> print (m)
None

>>> m = pattern.match('one12twothree34four', 2, 10) # 從'e'的位置開始匹配,沒有匹配
>>> print (m)
None

>>> m = pattern.match('one12twothree34four', 3, 10) # 從'1'的位置開始匹配,正好匹配
>>> print (m) # 返回一個 Match 對象
<_sre.SRE_Match object at 0x10a42aac0>

>>> m.group(0) # 可省略 0
'12'
>>> m.start(0) # 可省略 0
3
>>> m.end(0) # 可省略 0
5
>>> m.span(0) # 可省略 0
(3, 5)

在上面,當匹配成功時返回一個 Match 對象,其中:

group([group1, …]) 方法用于獲得一個或多個分組匹配的字符串,當要獲得整個匹配的子串時,可直接使用 group() 或 group(0);

start([group]) 方法用于獲取分組匹配的子串在整個字符串中的起始位置(子串第一個字符的索引),參數默認值為 0;

end([group]) 方法用于獲取分組匹配的子串在整個字符串中的結束位置(子串最后一個字符的索引+1),參數默認值為 0;

span([group]) 方法返回 (start(group), end(group))。

再看看一個例子:

>>> import re
>>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I 表示忽略大小寫
>>> m = pattern.match('Hello World Wide Web')

>>> print (m) # 匹配成功,返回一個 Match 對象
<_sre.SRE_Match object at 0x10bea83e8>

>>> m.group(0) # 返回匹配成功的整個子串
'Hello World'

>>> m.span(0) # 返回匹配成功的整個子串的索引
(0, 11)

>>> m.group(1) # 返回第一個分組匹配成功的子串
'Hello'

>>> m.span(1) # 返回第一個分組匹配成功的子串的索引
(0, 5)

>>> m.group(2) # 返回第二個分組匹配成功的子串
'World'

>>> m.span(2) # 返回第二個分組匹配成功的子串
(6, 11)

>>> m.groups() # 等價于 (m.group(1), m.group(2), ...)
('Hello', 'World')

>>> m.group(3) # 不存在第三個分組
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
IndexError: no such group

search 方法

search 方法用于查找字符串的任何位置,它也是一次匹配,只要找到了一個匹配的結果就返回,而不是查找所有匹配的結果,它的一般使用形式如下:

search(string[, pos[, endpos]])

其中,string 是待匹配的字符串,pos 和 endpos 是可選參數,指定字符串的起始和終點位置,默認值分別是 0 和 len (字符串長度)。

當匹配成功時,返回一個 Match 對象,如果沒有匹配上,則返回 None。

讓我們看看例子:

>>> import re
>>> pattern = re.compile('d+')
>>> m = pattern.search('one12twothree34four') # 這里如果使用 match 方法則不匹配
>>> m
<_sre.SRE_Match object at 0x10cc03ac0>
>>> m.group()
'12'
>>> m = pattern.search('one12twothree34four', 10, 30) # 指定字符串區間
>>> m
<_sre.SRE_Match object at 0x10cc03b28>
>>> m.group()
'34'
>>> m.span()
(13, 15)

再來看一個例子:

# -*- coding: utf-8 -*-

import re
# 將正則表達式編譯成 Pattern 對象
pattern = re.compile(r'd+')
# 使用 search() 查找匹配的子串,不存在匹配的子串時將返回 None
# 這里使用 match() 無法成功匹配
m = pattern.search('hello 123456 789')
if m:
 # 使用 Match 獲得分組信息
 print ('matching string:',m.group())
 # 起始位置和結束位置
 print ('position:',m.span())

執行結果:

matching string: 123456
position: (6, 12)

findall 方法

上面的 match 和 search 方法都是一次匹配,只要找到了一個匹配的結果就返回。然而,在大多數時候,我們需要搜索整個字符串,獲得所有匹配的結果。

findall 方法的使用形式如下:

findall(string[, pos[, endpos]])

其中,string 是待匹配的字符串,pos 和 endpos 是可選參數,指定字符串的起始和終點位置,默認值分別是 0 和 len (字符串長度)。

findall 以列表形式返回全部能匹配的子串,如果沒有匹配,則返回一個空列表。

看看例子:

import re
pattern = re.compile(r'd+') # 查找數字

result1 = pattern.findall('hello 123456 789')
result2 = pattern.findall('one1two2three3four4', 0, 10)

print (result1)
print (result2)

執行結果:

['123456', '789']
['1', '2']

再先看一個栗子:

# re_test.py

import re

#re模塊提供一個方法叫compile模塊,提供我們輸入一個匹配的規則
#然后返回一個pattern實例,我們根據這個規則去匹配字符串
pattern = re.compile(r'd+.d*')

#通過partten.findall()方法就能夠全部匹配到我們得到的字符串
result = pattern.findall("123.141593, 'bigcat', 232312, 3.15")

#findall 以 列表形式 返回全部能匹配的子串給result
for item in result:
 print (item)

運行結果:

123.141593
3.15

finditer 方法

finditer 方法的行為跟 findall 的行為類似,也是搜索整個字符串,獲得所有匹配的結果。但它返回一個順序訪問每一個匹配結果(Match 對象)的迭代器。

看看例子:

# -*- coding: utf-8 -*-

import re
pattern = re.compile(r'd+')

result_iter1 = pattern.finditer('hello 123456 789')
result_iter2 = pattern.finditer('one1two2three3four4', 0, 10)

print (type(result_iter1))
print (type(result_iter2))

print 'result1...'
for m1 in result_iter1: # m1 是 Match 對象
 print ('matching string: {}, position: {}'.format(m1.group(), m1.span()))

print 'result2...'
for m2 in result_iter2:
 print ('matching string: {}, position: {}'.format(m2.group(), m2.span()))

執行結果:

<type 'callable-iterator'>
<type 'callable-iterator'>
result1...
matching string: 123456, position: (6, 12)
matching string: 789, position: (13, 16)
result2...
matching string: 1, position: (3, 4)
matching string: 2, position: (7, 8)

split 方法

split 方法按照能夠匹配的子串將字符串分割后返回列表,它的使用形式如下:

split(string[, maxsplit])

其中,maxsplit 用于指定最大分割次數,不指定將全部分割。

看看例子:

import re
p = re.compile(r'[s,;]+')
print (p.split('a,b;; c d'))

執行結果:

['a', 'b', 'c', 'd']

sub 方法

sub 方法用于替換。它的使用形式如下:

sub(repl, string[, count])

其中,repl 可以是字符串也可以是一個函數:

如果 repl 是字符串,則會使用 repl 去替換字符串每一個匹配的子串,并返回替換后的字符串,另外,repl 還可以使用 id 的形式來引用分組,但不能使用編號 0;

如果 repl 是函數,這個方法應當只接受一個參數(Match 對象),并返回一個字符串用于替換(返回的字符串中不能再引用分組)。

count 用于指定最多替換次數,不指定時全部替換。

看看例子:

import re
p = re.compile(r'(w+) (w+)') # w = [A-Za-z0-9]
s = 'hello 123, hello 456'

print (p.sub(r'hello world', s)) # 使用 'hello world' 替換 'hello 123' 和 'hello 456'
print (p.sub(r'2 1', s)) # 引用分組

def func(m):
 print(m)
 return 'hi' + ' ' + m.group(2) #group(0) 表示本身,group(1)表示hello,group(2) 表示后面的數字

print (p.sub(func, s)) #多次sub,每次sub的結果傳遞給func
print (p.sub(func, s, 1)) # 最多替換一次

執行結果:

hello world, hello world
123 hello, 456 hello
hi 123, hi 456
hi 123, hello 456

匹配中文

在某些情況下,我們想匹配文本中的漢字,有一點需要注意的是,中文的 unicode 編碼范圍 主要在 [u4e00-u9fa5],這里說主要是因為這個范圍并不完整,比如沒有包括全角(中文)標點,不過,在大部分情況下,應該是夠用的。

假設現在想把字符串 title = u’你好,hello,世界’ 中的中文提取出來,可以這么做:

import re

title = '你好,hello,世界'
pattern = re.compile(r'[\u4e00-\u9fa5]+')
result = pattern.findall(title)

print (result)

注意到,我們在正則表達式前面加上了兩個前綴 ur,其中 r 表示使用原始字符串,u 表示是 unicode 字符串。

執行結果:

['你好', '世界']

注意:貪婪模式與非貪婪模式

貪婪模式:在整個表達式匹配成功的前提下,盡可能多的匹配 ( * );
非貪婪模式:在整個表達式匹配成功的前提下,盡可能少的匹配 ( ? );
Python里數量詞默認是貪婪的。

示例一 : 源字符串:abbbc

使用貪婪的數量詞的正則表達式 ab* ,匹配結果: abbb。

  • 決定了盡可能多匹配 b,所以a后面所有的 b 都出現了。

使用非貪婪的數量詞的正則表達式ab*?,匹配結果: a。

即使前面有 *,但是 ? 決定了盡可能少匹配 b,所以沒有 b。

示例二 : 源字符串:

aa<div>test1</div>bb<div>test2</div>cc
使用貪婪的數量詞的正則表達式:<div>.*</div>

匹配結果:<div>test1</div>bb<div>test2</div>

這里采用的是貪婪模式。在匹配到第一個"“時已經可以使整個表達式匹配成功,但是由于采用的是貪婪模式,所以仍然要向右嘗試匹配,查看是否還有更長的可以成功匹配的子串。匹配到第二個”“后,向右再沒有可以成功匹配的子串,匹配結束,匹配結果為”<div>test1</div>bb<div>test2</div>"

使用非貪婪的數量詞的正則表達式:<div>.*?</div>

匹配結果:<div>test1</div>

正則表達式二采用的是非貪婪模式,在匹配到第一個""時使整個表達式匹配成功,由于采用的是非貪婪模式,所以結束匹配,不再向右嘗試,匹配結果為"<div>test1</div>"。



Tags:Python 正則表達式   點擊:()  評論:()
聲明:本站部分內容來自互聯網,內容觀點僅代表作者本人,如有任何版權侵犯請與我們聯系,我們將立即刪除。
▌相關評論
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
▌相關推薦
為什么要學正則表達式實際上爬蟲一共就四個主要步驟:明確目標 (要知道你準備在哪個范圍或者網站去搜索) 爬 (將所有的網站的內容全部爬下來) 取 (去掉對我們沒用處的數據) 處...【詳細內容】
2019-11-22   Python 正則表達式  點擊:(3)  評論:(0)  加入收藏
正則表達式是一個很強大的字符串處理工具,幾乎任何關于字符串的操作都可以使用正則表達式來完成,作為一個爬蟲工作者,每天和字符串打交道,正則表達式更是不可或缺的技能。正則表...【詳細內容】
2019-08-07   Python 正則表達式  點擊:(36)  評論:(0)  加入收藏
最新更新
欄目熱門
欄目頭條
31选7开奖11185