python中re模塊


1.定義

 正則表達式是一個特殊的字符序列,能方便的檢查一個字符串是否與某種模式匹配。re模塊使得python擁有全部的正則表達式功能。

2.用途

通過使用正則表達式,可以:
測試字符串內的模式。—— 例如,可以測試輸入字符串,以查看字符串內是否出現電話號碼模式或信用卡號碼模式。這稱為數據驗證。
替換文本。—— 可以使用正則表達式來識別文檔中的特定文本,完全刪除該文本或者用其他文本替換它。
基於模式匹配從字符串中提取子字符串。—— 可以查找文檔內或輸入域內特定的文本。

3.語法

'.'     匹配所有字符串,除\n以外
'-'     表示范圍[0-9]
'*'     匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*'+'     匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+
'^'     匹配字符串開頭
'$'     匹配字符串結尾 re
'\'     轉義字符, 使后一個字符改變原來的意思,如果字符串中有字符*需要匹配,可以\*或者字符集[*] re.findall(r'3\*','3*ds')結['3*']
'*'     匹配前面的字符0次或多次 re.findall("ab*","cabc3abcbbac")結果:['ab', 'ab', 'a']
'?'     匹配前一個字符串0次或1次 re.findall('ab?','abcabcabcadf')結果['ab', 'ab', 'ab', 'a']
'{m}'   匹配前一個字符m次 re.findall('cb{1}','bchbchcbfbcbb')結果['cb', 'cb']
'{n,m}' 匹配前一個字符n到m次 re.findall('cb{2,3}','bchbchcbfbcbb')結果['cbb']
'\d'    匹配數字,等於[0-9] re.findall('\d','電話:10086')結果['1', '0', '0', '8', '6']
'\D'    匹配非數字,等於[^0-9] re.findall('\D','電話:10086')結果['電', '話', ':']
'\w'    匹配字母和數字,等於[A-Za-z0-9] re.findall('\w','alex123,./;;;')結果['a', 'l', 'e', 'x', '1', '2', '3']
'\W'    匹配非英文字母和數字,等於[^A-Za-z0-9] re.findall('\W','alex123,./;;;')結果[',', '.', '/', ';', ';', ';']
'\s'    匹配空白字符 re.findall('\s','3*ds \t\n')結果[' ', '\t', '\n']
'\S'    匹配非空白字符 re.findall('\s','3*ds \t\n')結果['3', '*', 'd', 's']
'\A'    匹配字符串開頭
'\Z'    匹配字符串結尾
'\b'    匹配單詞的詞首和詞尾,單詞被定義為一個字母數字序列,因此詞尾是用空白符或非字母數字符來表示的
'\B'    與\b相反,只在當前位置不在單詞邊界時匹配
[]      是定義匹配的字符范圍。比如 [a-zA-Z0-9] 表示相應位置的字符要匹配英文字符和數字。[\s*]表示空格或者*'(?P<name>...)'  分組,除了原有編號外在指定一個額外的別名 
re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{8})","371481199306143242").groupdict("city") 
結果{'province': '3714', 'city': '81', 'birthday': '19930614'}

4.模式

貪婪模式和非貪婪模式

正則表達式通常使用於查找匹配字符串。python里數量詞默認是貪婪的,總是嘗試匹配盡可能多的字符;非貪婪模式正好相反,總是嘗試匹配盡可能少的字符。

使用方法

在python中默認采用的是貪婪模式,使用非貪婪模式的話,只需要在量詞后面直接加上一個問號”?”。

例子當中已經匹配到了“ab”時已經可以使整個表達式匹配成功,但是由於采用的是貪婪模式,所以還需要往后繼續匹配,一直到匹配到最后一個”b”的時候,后面已經沒有可以成功匹配的字符串了,匹配結束。返回匹配結果“abbbbbb”。 所以,我們可以將貪婪模式理解為:在整個表達式匹配成功的前提下,盡可能多的匹配。

非貪婪模式也就是將我們例子中的正則表達式“ab+”改為”ab+?”,當匹配到“ab”時,已經匹配成功,直接結束匹配,不在向后繼續嘗試,返回匹配成功的字符串”ab”。
所以,我們可以將非貪婪模式理解為:在整個表達式匹配成功的前提下,盡可能少的匹配

import re

example = "<div>test1</div><div>test2</div>"

greedPattern = re.compile("<div>.*</div>")
notGreedPattern = re.compile("<div>.*?</div>")

greedResult = greedPattern.search(example)
notGreedResult = notGreedPattern.search(example)

print("greedResult = %s" % greedResult.group())
print("notGreedResult = %s" % notGreedResult.group())
[python@master test]$ python3 a.py 
greedResult = <div>test1</div><div>test2</div>
notGreedResult = <div>test1</div>

能達到同樣匹配結果的貪婪與非貪婪模式,通常是貪婪模式的匹配效率較高。 所有的非貪婪模式,都可以通過修改量詞修飾的子表達式,轉換為貪婪模式。 貪婪模式可以與固化分組結合,提升匹配效率,而非貪婪模式卻不可以。

5.使用re模塊

反斜杠的困擾

在 python 的字符串中,\ 是被當做轉義字符的。在正則表達式中,\ 也是被當做轉義字符。這就導致了一個問題:如果你要匹配 \ 字符串,那么傳遞給 re.compile() 的字符串必須是"\\\\"。

由於字符串的轉義,所以實際傳遞給 re.compile() 的是"\\",然后再通過正則表達式的轉義,"\\" 會匹配到字符"\"。這樣雖然可以正確匹配到字符 \,但是很麻煩,而且容易漏寫反斜杠而導致 Bug。那么有什么好的解決方案呢?

原始字符串很好的解決了這個問題,通過在字符串前面添加一個r,表示原始字符串,不讓字符串的反斜杠發生轉義。那么就可以使用r"\\"來匹配字符\了。

re.compile()

編譯正則表達式模式,返回一個對象。可以把常用的正則表達式編譯成正則表達式對象,方便后續調用及提高效率。

re.compile(pattern,flags=0)

     pattern 指定編譯時的表達式字符串

     flags     編譯標志位,用來修改正則表達式的匹配方式。支持 re.L|re.M 同時匹配

flags 標志位參數
re.I(re.IGNORECASE)     使匹配對大小寫不敏感
re.L(re.LOCAL)               做本地化識別(locale-aware)匹配
re.M(re.MULTILINE)         多行匹配,影響 ^ 和 $
re.S(re.DOTALL)             使 . 匹配包括換行在內的所有字符
re.U(re.UNICODE)           根據Unicode字符集解析字符。這個標志影響 \w, \W, \b, \B.
re.X(re.VERBOSE)          該標志通過給予你更靈活的格式以便你將正則表達式寫得更易於理解

import re
content = 'Citizen wang , always fall in love with neighbour,WANG'
rr = re.compile(r'wan\w', re.I) # 不區分大小寫
print(type(rr))
a = rr.findall(content)
print(type(a))
print(a)
[python@master test]$ python3 b.py 
<class 're.Pattern'>
<class 'list'>
['wang', 'WANG']

re.match

嘗試從一個字符串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,則返回None。

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

pattern: 待匹配的正則表達式
string: 待查找的字符串
flags(可選參數): 標志位,控制正則表達式的匹配方式。re.I(ignore) re.L(local) re.M(many lines) re.S(sum) re.U(unicode) re.X
返回值:匹配成功返回匹配對象(group(num=0) / groups() 返回的是一個元組),匹配失敗返回None

我們可以使用group(num) 或 groups() 匹配對象函數來獲取匹配表達式

    group(num=0)    匹配的整個表達式的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。

    groups()            返回一個包含所有小組字符串的元組,從 1 到 所含的小組號。

列子1:

[python@master test]$  more  d.py
# -*- coding: UTF-8 -*-

import re
print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配
[python@master test]$ python3 d.py 
(0, 3)
None

例子二:

[python@master test]$ more c.py 
import re

line = "Cats are Smarter than dogs"
# re.M:多行匹配
# re.I:忽略大小寫進行匹配
# match()以元組形式返回匹配成功的對象
match_obj = re.match(r"(.*) are (.*?) .*", line, re.M | re.I)
if match_obj:
    print("match_obj.group(): ", match_obj.group())
    print("match_obj.group(1): ", match_obj.group(1))
    print("match_obj.group(2): ", match_obj.group(2))
    print("match_obj.group(3): ", match_obj.group(1,2))
    print("match_obj.groups(): ", match_obj.groups())
else:
    print("None match!")
print("*" * 98)
[python@master test]$ python3 c.py 
match_obj.group():  Cats are Smarter than dogs
match_obj.group(1):  Cats
match_obj.group(2):  Smarter
match_obj.group(3):  ('Cats', 'Smarter')
match_obj.groups():  ('Cats', 'Smarter')
**************************************************************************************************

re.search

掃描整個字符串並返回第一個成功的匹配。
函數語法:
re.search(pattern, string, flags=0)
函數參數說明:
pattern        匹配的正則表達式
string          要匹配的字符串。
flags            標志位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。


匹配成功re.search方法返回一個匹配的對象,否則返回None。
我們可以使用group(num) 或 groups() 匹配對象函數來獲取匹配表達式。
     group(num=0)    匹配的整個表達式的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。
     groups()            返回一個包含所有小組字符串的元組,從 1 到 所含的小組號。

例子1:

[python@master test]$ more a.py 
# -*- coding: UTF-8 -*- 
 
import re
print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配
[python@master test]$ python3 a.py 
(0, 3)
(11, 14)

例子2:

[python@master test]$ more b.py 
import re
 
line = "Cats are smarter than dogs";
 
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
 
if searchObj:
   print("searchObj.group() : ", searchObj.group())
   print("searchObj.group(1) : ", searchObj.group(1))
   print("searchObj.group(2) : ", searchObj.group(2))
else:
   print("Nothing found!!")
[python@master test]$ python3 b.py 
searchObj.group() :  Cats are smarter than dogs
searchObj.group(1) :  Cats
searchObj.group(2) :  smarter

re.match與re.search的區別

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

[python@master test]$ more c.py 
import re
 
line = "Cats are smarter than dogs";
 
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print("match --> matchObj.group() : ", matchObj.group())
else:
   print("No match!!")
 
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
   print("search --> matchObj.group() : ", matchObj.group())
else:
   print("No match!!")
[python@master test]$ python3 c.py 
No match!!
search --> matchObj.group() :  dogs

re.sub()

Python 的 re 模塊提供了re.sub用於替換字符串中的匹配項。
語法:
re.sub(pattern, repl, string, count=0, flags=0)
參數:
pattern       正則中的模式字符串。
repl            替換的字符串,也可為一個函數。
string         要被查找替換的原始字符串。
count         模式匹配后替換的最大次數,默認 0 表示替換所有的匹配。

[python@master test]$ more d.py
import re
 
phone = "2004-959-559 # 這是一個電話號碼"
 
# 刪除注釋
num = re.sub(r'#.*$', "", phone)
print ("電話號碼 : ", num)
 
# 移除非數字的內容
num = re.sub(r'\D', "", phone)
print ("電話號碼 : ", num)
[python@master test]$ python3 d.py 
電話號碼 :  2004-959-559 
電話號碼 :  2004959559

repl 參數是一個函數

以下實例中將字符串中的匹配的數字乘於 2

[python@master test]$ more e.py 
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))
[python@master test]$ python3 e.py 
A46G8HFD1134

findall()

在字符串中找到正則表達式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。
注意: match 和 search 是匹配一次 findall 匹配所有。
語法格式為:
findall(string[, pos[, endpos]])
參數:
string           待匹配的字符串。
pos              可選參數,指定字符串的起始位置,默認為 0。
endpos           可選參數,指定字符串的結束位置,默認為字符串的長度。
查找字符串中的所有數字:

[python@master test]$ more a.py 
import re
 
pattern = re.compile(r'\d+')   # 查找數字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
 
print(result1)
print(result2)
[python@master test]$ python3 a.py 
['123', '456']
['88', '12']

re.finditer() 

和 findall 類似,在字符串中找到正則表達式所匹配的所有子串,並把它們作為一個迭代器返回。
re.finditer(pattern, string, flags=0)
參數:
pattern         匹配的正則表達式
string         要匹配的字符串。
flags           標志位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。

[python@master test]$ more d.py 
import re
 
it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )
[python@master test]$ python3 d.py 
12
32
43
3

re.split()

split 方法按照能夠匹配的子串將字符串分割后返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
參數:
pattern           匹配的正則表達式
string           要匹配的字符串。
maxsplit         分隔次數,maxsplit=1 分隔一次,默認為 0,不限制次數。
flags             標志位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等

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

 

正則表達式對象 

re.RegexObject
re.compile() 返回 RegexObject 對象。
re.MatchObject
   group() 返回被 RE 匹配的字符串。
   start() 返回匹配開始的位置
   end()   返回匹配結束的位置
   span()  返回一個元組包含匹配 (開始,結束) 的位置   

正則表達式模式

模式字符串使用特殊的語法來表示一個正則表達式:
字母和數字表示他們自身。一個正則表達式模式中的字母和數字匹配同樣的字符串。
多數字母和數字前加一個反斜杠時會擁有不同的含義。
標點符號只有被轉義時才匹配自身,否則它們表示特殊的含義。
反斜杠本身需要使用反斜杠轉義。
由於正則表達式通常都包含反斜杠,所以你最好使用原始字符串來表示它們。模式元素(如 r'\t',等價於 \\t )匹配相應的特殊字符。
下表列出了正則表達式模式語法中的特殊元素。如果你使用模式的同時提供了可選的標志參數,某些模式元素的含義會改變。

^                 匹配字符串的開頭
$                 匹配字符串的末尾。
.                 匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字符。
[...]             用來表示一組字符,單獨列出:[amk] 匹配 'a''m''k'
[^...]            不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*               匹配0個或多個的表達式。
re+               匹配1個或多個的表達式。
re?               匹配0個或1個由前面的正則表達式定義的片段,非貪婪方式
re{ n}            匹配n個前面表達式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的兩個o。
re{ n,}           精確匹配n個前面表達式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等價於"o+"。"o{0,}"則等價於"o*"。
re{ n, m}         匹配 n 到 m 次由前面的正則表達式定義的片段,貪婪方式
a| b              匹配a或b
(re)              匹配括號內的表達式,也表示一個組
(?imx)            正則表達式包含三種可選標志:i, m, 或 x 。只影響括號中的區域。
(?-imx)           正則表達式關閉 i, m, 或 x 可選標志。只影響括號中的區域。
(?: re)           類似 (...), 但是不表示一個組
(?imx: re)        在括號中使用i, m, 或 x 可選標志
(?-imx: re)       在括號中不使用i, m, 或 x 可選標志
(?#...)           注釋.
(?= re)           前向肯定界定符。如果所含正則表達式,以 ... 表示,在當前位置成功匹配時成功,否則失敗。但一旦所含表達式已經嘗試,匹配引擎根本沒有提高;模式的剩余部分還要嘗試界定符的右邊。
(?! re)           前向否定界定符。與肯定界定符相反;當所含表達式不能在字符串當前位置匹配時成功。
(?> re)           匹配的獨立模式,省去回溯。
\w                匹配數字字母下划線
\W                匹配非數字字母下划線
\s                匹配任意空白字符,等價於 [\t\n\r\f]。
\S                匹配任意非空字符
\d                匹配任意數字,等價於 [0-9]。
\D                匹配任意非數字
\A                匹配字符串開始
\Z                匹配字符串結束,如果是存在換行,只匹配到換行前的結束字符串。
\z                匹配字符串結束
\G                匹配最后匹配完成的位置。
\b                匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B                匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等。       匹配一個換行符。匹配一個制表符, 等
\1...\9           匹配第n個分組的內容。
\10               匹配第n個分組的內容,如果它經匹配。否則指的是八進制字符碼的表達式。

正則表達式實例

[Pp]ython           匹配 "Python" 或 "python"    
rub[ye]               匹配 "ruby" 或 "rube"          
[aeiou]               匹配中括號內的任意一個字母     
[0-9]                   匹配任何數字。類似於 [0123456789]
[a-z]                   匹配任何小寫字母                 
[A-Z]                  匹配任何大寫字母                 
[a-zA-Z0-9]        匹配任何字母及數字         
[^aeiou]              除了aeiou字母以外的所有字符  
[^0-9]                 匹配除了數字外的字符

 特殊字符類 

.                  匹配除 "\n" 之外的任何單個字符。要匹配包括 '\n' 在內的任何字符,請使用象 '[.\n]' 的模式。    
\d                匹配一個數字字符。等價於 [0-9]。                                                       
\D                匹配一個非數字字符。等價於 [^0-9]。                                                    
\s                匹配任何空白字符,包括空格、制表符、換頁符等等。等價於 [ \f\n\r\t\v]。                 
\S                匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。                                            
\w                匹配包括下划線的任何單詞字符。等價於'[A-Za-z0-9_]'。                                   
\W               匹配任何非單詞字符。等價於 '[^A-Za-z0-9_]'。  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM