1. 程式人生 > 實用技巧 >你說要你想玩爬蟲,但你說你不懂Python正則表示式,我信你個鬼,那你還不來看看?

你說要你想玩爬蟲,但你說你不懂Python正則表示式,我信你個鬼,那你還不來看看?

前言

正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。

re 模組也提供了與這些方法功能完全一致的函式,這些函式使用一個模式字串做為它們的第一個引數。

re.match函式

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

函式語法

re.match(pattern, string, flags=0)

函式引數說明:

引數 描述
pattern 匹配的正則表示式
string 要匹配的字串。
flags 標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

匹配成功re.match方法返回一個匹配的物件,否則返回None。

我們可以使用group(num) 或 groups() 匹配物件函式來獲取匹配表示式。

匹配物件方法 描述
group(num=0) 匹配的整個表示式的字串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。
groups() 返回一個包含所有小組字串的元組,從 1 到 所含的小組號。

例項:

import re

line = "I really like you yesterday"

matchObj = re.match( r'(.*) really (.*?) .*', line)

print ("matchObj.group() : ", matchObj.group())print ("matchObj.group(1) : ", matchObj.group(1))print ("matchObj.group(2) : ", matchObj.group(2))

以上例項執行結果如下:

matchObj.group() :  I really like you yesterdaymatchObj.group(1) :  ImatchObj.group(2) :  like

re.search方法

re.search 會在字串內查詢模式匹配,直到找到第一個匹配。

函式語法:

re.search(pattern, string, flags=0)

函式引數說明:

引數 描述
pattern 匹配的正則表示式
string 要匹配的字串。
flags 標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

匹配成功re.search方法返回一個匹配的物件,否則返回None。

我們可以使用group(num) 或 groups() 匹配物件函式來獲取匹配表示式。

匹配物件方法 描述
group(num=0) 匹配的整個表示式的字串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。
groups() 返回一個包含所有小組字串的元組,從 1 到 所含的小組號。

例項:

#!/usr/bin/python
import re

line = "I really like you yesterday";

searchObj = re.search(r'(.*) really (.*?) .*', line)

print ("searchObj.group() : ", searchObj.group())
print ("searchObj.group(1) : ", searchObj.group(1))
print ("searchObj.group(2) : ", searchObj.group(2))

以上例項執行結果如下:

searchObj.group() : I really like you yesterday
searchObj.group(1) :  I
searchObj.group(2) :  love

re.match與re.search的區別

re.match只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,直到找到一個匹配。

例項:

#!/usr/bin/python
import re

line = "I really like you yesterday";
matchObj = re.match( r'love', line)
if matchObj:
   print("match --> matchObj.group() : ", matchObj.group())
else:
   print "No match!!"

matchObj = re.search( r'love', line)
if matchObj:
   print "search --> matchObj.group() : ", matchObj.group()
else:
   print "No match!!"

以上例項執行結果如下:

No match!!
search --> matchObj.group() :  love

檢索和替換

Python 的re模組提供了re.sub用於替換字串中的匹配項。

語法:

re.sub(pattern, repl, string, max=0)

返回的字串是在字串中用 RE 最左邊不重複的匹配來替換。如果模式沒有發現,字元將被沒有改變地返回。

可選引數 count 是模式匹配後替換的最大次數;count 必須是非負整數。預設值是 0 表示替換所有的匹配。

例項:

import re
 
phone = "2004-959-559 # 這是一個國外電話號碼"
 
# 刪除字串中的 Python註釋
num = re.sub(r'#.*$', "", phone)
print("電話號碼是: ", num)
 
# 刪除非數字(-)的字串
num = re.sub(r'\D', "", phone)
print("電話號碼是 : ", num)

以上例項執行結果如下:

電話號碼 :  2004-959-559
電話號碼 :  2004959559

repl 引數是一個函式

以下例項中將字串中的匹配的數字乘以 2:

例項:

import re
 
# 將匹配的數字乘以 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)
 
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

執行輸出結果為:

A46G8HFD1134

re.compile 函式

compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,供 match() 和 search() 這兩個函式使用。

語法格式為:

re.compile(pattern[, flags])

引數:

  • pattern : 一個字串形式的正則表示式

  • flags : 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:

    1. re.I 忽略大小寫
    2. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境
    3. re.M 多行模式
    4. re.S 即為 . 並且包括換行符在內的任意字元(. 不包括換行符)
    5. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴於 Unicode 字元屬性資料庫
    6. re.X 為了增加可讀性,忽略空格和 # 後面的註釋

例項

>>>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

findall

在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。

注意:match 和 search 是匹配一次 findall 匹配所有。

語法格式為:

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

引數:

  • string : 待匹配的字串。
  • pos : 可選引數,指定字串的起始位置,預設為 0。
  • endpos : 可選引數,指定字串的結束位置,預設為字串的長度。

查詢字串中的所有數字:

import re
 
pattern = re.compile(r'\d+')   # 查詢數字
result1 = pattern.findall('school 123 google 456')
result2 = pattern.findall('sch88ool123google456', 0, 10) 
print(result1)
print(result2)

輸出結果:

['123', '456']
['88', '12']

re.finditer

和 findall 類似,在字串中找到正則表示式所匹配的所有子串,並把它們作為一個迭代器返回。

re.finditer(pattern, string, flags=0)

引數:

引數 描述
pattern 匹配的正則表示式
string 要匹配的字串。
flags 標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

例項:

import re
 
it = re.finditer(r"\d+","12a32bc43jf3")
for match in it:
    print (match.group() )

輸出結果:

12
32
43
3

re.split

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

re.split(pattern, string[, maxsplit=0, flags=0])

引數:

引數 描述
pattern 匹配的正則表示式
string 要匹配的字串。
maxsplit 分隔次數,maxsplit=1 分隔一次,預設為 0,不限制次數。
flags 標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

例項:

>>>import re
>>> re.split('\W+', 'school, school, chool.')
['runoob', 'runoob', 'w3cschool', '']
>>> re.split('(\W+)', ' school, school, school.')
['', ' ', 'runoob', ', ', 'school', ', ', 'school', '.', '']
>>> re.split('\W+', ' w3cschool, w3cschool, w3cschool.', 1)
['', 'school, school, school.']
 
>>> re.split('a*', 'hello world')   # 對於一個找不到匹配的字串而言,split 不會對其作出分割
['hello world']

如果對軟體測試、介面測試、自動化測試、持續整合、面試經驗。感興趣可以進到902061117,群內會有不定期的分享測試資料。還會有技術大牛,業內同行一起交流技術