第一章 正規表示式

2021-08-20 10:02:47 字數 3774 閱讀 9228

正規表示式是高階的文字模式匹配、抽取、或文字形式的搜尋和替換功能提供了基礎。正規表示式(簡稱regex)是由一些字元或特殊符號組成的字串,他們描述了模式的重複或表述多個字元,於是正規表示式能夠按照某一模式匹配一系列有相似特徵的字串。python使用re模組來支援正規表示式。

符號描述

*匹配0次或者多次前面出現的正規表示式

+匹配一次或者多次出現前面的正規表示式

?匹配0次或者1次前面出現的正規表示式

.匹配任何字元除了換行符

^匹配字串開始部分

$匹配字串結束部分

\d匹配任何十進位制數字,與[0-9]一致

\w匹配任何字母數字字元

字符集支援匹配指定的字元範圍,方括號中兩個符號中間用『-』連線,用於指定乙個字元的範圍。例如:a-z、a-z、或者0-9分別表示大寫字母、小寫字母、數字。如果脫字元『^』緊跟左方括號後面,這個符號就表示不匹配給定字符集中的任何乙個字元。例如『[^aeiou]』表示乙個非母音字元。

閉包操作符指的是上文提到的.、*、?;除了這三個還有大括號操作符,裡面是單個值或者是一對由逗號分離的值,,這將最終精確地匹配前面的正規表示式m次或者m到n次。

如果?號之前是非閉包操作符,這表示要麼匹配0次要麼匹配1次。

如果?號之前是閉包操作符,它將直接要求正規表示式引擎匹配盡可能少的次數。

當模式使用分組操作符時,正規表示式引擎試圖吸收匹配該模式盡可能多的字元,這也就是貪婪匹配

上文所說盡可能少的次數是說盡可能少的匹配字元,也就是非貪婪匹配。

對正規表示式進行分組

匹配子組

compile(pattern,flag=0):使用任何可選的標記來編譯正規表示式的模式,然後返回乙個正規表示式物件

經過預編譯階段,生成**物件比直接使用的字串要快,正規表示式在執行過程中將進行多次比較操作,因此建議預編譯。

pattern = re.compile(r'([a-z]+) ([a-z]+)',re.i)  #預編譯

m = pattern.match('hello world python regex') #match方法

print(m.group(0)) #輸出『hello world』

當處理正規表示式時,除了正規表示式物件外,還有乙個物件型別:匹配物件。也就是成功呼叫match()和search()函式返回的物件。group()要麼返回整個匹配物件,要麼根據要求返回特定子組。

match(pattern,string,flags=0)函式試圖從字串的起始部分對模式進行匹配,如果匹配成功,就返回乙個匹配物件;如果匹配失敗,返回none。

line = "cats are 1 are smarter than dogs"

matchobj = re.match(r'(.*) are (.*?) .*', line, re.m | re.i) #re.i 不區分大小寫標記

if matchobj:

print("matchobj.group() : ", matchobj.group()) #輸出 cats are 1 are smarter than dogs

print("matchobj.group(1) : ", matchobj.group(1)) #輸出 cats are 1 (貪婪匹配)

print("matchobj.group(2) : ", matchobj.group(2)) #輸出 smarter (非貪婪匹配)

search(pattern,string,flag=0)工作方式與match函式一致,不同之處在於search會用它的字串引數,在任意位置對給定正規表示式模式搜尋第一次出現的匹配情況,如果成功返回匹配,否則返回none

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!!") #true

matchobj = re.search(r'dogs', line, re.m | re.i)

if matchobj:

print("search --> matchobj.group() : ", matchobj.group()) #輸出 dogs

else:

print("no match!!")

正規表示式最常見的情況包括特殊字元的使用、正規表示式模式的重複出現,以及使用圓括號對匹配模式的各部分進行分組和提取操作。例如乙個郵件的正規表示式:

『\w+@\w+.com』

但是,假如新增了網域名稱前的主機名稱,例如www.***.com,改造後的正規表示式為:

『\w+@(\w+.)?\w+.com』

接下來進一步擴充套件,允許任意數量的中間子網域名稱存在

『\w+@(\w+.)*\w+.com』

patt = '(\w\w\w)-(\d\d\d)'

m = re.match(patt,'abc-123')

print(m.group()) #輸出 abc-123

print(m.group(1)) #輸出 abc

print(m.group(2)) #輸出 123

print(m.groups()) #輸出 ('abc', '123')

findall()函式查詢字串中某個正規表示式模式全部的非重複出現情況,與search()函式類似,但是findall()返回乙個列表,如果沒有匹配返回乙個空列表。

finditer()函式與findall函式功能類似,但是更節省記憶體。

str = 'this and that'

print(re.findall('(th\w+)',str)) #輸出 ['this', 'that']

it = re.finditer(r'(th\w+)',str)

#書中給出的是it.next(),python3上提示有問題,參照如下修改

g = next(it)

print(g.groups()) #輸出 ('this',)

print(g.group(1)) #輸出 this

g = next(it)

print(g.groups()) #輸出 ('that',)

這兩個函式都是將某字串中所有匹配正規表示式的部分進行某種形式的替換,用來替換的部分通常是乙個字串,或者是乙個函式,函式返回乙個用來替換的字串。subn()還返回乙個替換的總數,替換後的字串和表示替換總數的數字一起作為乙個擁有兩個元素的元組返回。

sub(pattern, repl, string, count=0, flags=0):

其中repl代表替換字串

m = re.sub('[ae]','zhang','abcdef')

print(m) #輸出 zhangbcdzhangf

m = re.subn('[ae]','zhang','abcdef')

print(m) #輸出 ('zhangbcdzhangf', 2)

python正規表示式 第一章

正規表示式包 re re.search pattern,string 其中pattern是字串形式提供的正規表示式,string是需要匹配的字串 使用 和 測試string有pattern完整匹配 re.search 0123456799 2 none true 只要有乙個匹配成功,就會返回true...

python 核心程式設計》第一章 正規表示式

import rem re.match foo bar foo print m.group footype m.group strm.group 返回匹配的字串 pattern foo bar m re.match pattern,foobarfooooooook print m.group foo...

第一章 文字 re 正規表示式 多重匹配

1.3.3 多重匹配 到目前為止,示例模式都只是使用search 來查詢字面量文字字串的單個例項。findall 函式會返回輸入中與模式匹配而且不重疊的所有子串。import re text abbaaabbbbaaaaa pattern ab for match in re.findall pat...