python--關於正則表達式的學習小結

python中提供了re這個模塊提供對正則表達式的支持。python

1、正則表達式經常使用到的一些語法(並不是所有):正則表達式

. 匹配任意單個字符
[...] 匹配單個字符集
\w 匹配單詞字符,即[a-zA-Z0-9]
\W 匹配非單詞字符集,例如 ‘*’
\d 匹配數字,即[0-9]
\D 匹配非數字
\s 匹配空白字符
\S 匹配非空白字符
* 匹配前一個字符0次或者任意屢次
+ 匹配前一個字符1次或者任意屢次
? 匹配前一個字符0次或者1次
{m} 匹配前一個字符m次
{m,n} 匹配前一個字符最少m次,最多n次
*? 非貪婪模式匹配前一個字符0次或者任意屢次
+? 非貪婪模式匹配前一個字符1次或者任意屢次
?? 非貪婪模式匹配前一個字符0次或者1次
{m,n}? 非貪婪模式匹配前一個字符最少m次,最多n次
^ 匹配字符串開頭
$ 匹配字符串結尾
\A 制定的字符串匹配必須出如今開頭
\Z 制定的字符串匹配必須出如今結尾
| 匹配左右任意一個表達式,至關於「或」的含義
() 匹配一個分組,括號中爲該分組所需匹配的內容
\<number> 引用匹配編號爲<number>的分組中的字符串
(?P<group_name>) 爲匹配分組制定特定的組名
(?P=<group_name>) 引用特定組名的匹配字符串

幾點解釋:函數

1. 兩種方式均可以進行匹配:spa

(1)首先建立pattern,而後進行matchcode

1 pa = re.compile(r'[\w]{6}') # 首先利用re模塊建立一個pattern實例pa
2 ma = pa.match('string')  # 利用這一pattern對正則表達式進行匹配
3 ma.group()  #打印匹配的內容,輸出爲'string'

(2)直接利用re模塊中的函數match進行匹配對象

1 ma = re.match(r'[\w]{6}', ‘string’)
2 print(ma.group())  # 打印匹配的內容,輸出爲'string'

 

2. 貪婪模式和非貪婪模式:blog

貪婪模式:老是嘗試匹配儘量多的字符;ci

非貪婪模式:老是嘗試匹配儘量少的字符。字符串

例如:利用正則表達式‘python*’匹配‘pythonnnnnpython’,此時ma = re.match(r'python*',‘pythonnnpython’),獲得的ma.group()爲‘pythonnn’;利用‘python*?’進行匹配,此時ma = re.match(r'python*?',‘pythonnnpython’),獲得的ma.group()爲‘python’。博客

 

3. 關於邏輯與分組語法的用法:

| 匹配左右任意一個表達式,至關於「或」的含義
() 匹配一個分組,括號中爲該分組所需匹配的內容
\<number> 引用匹配編號爲<number>的分組中的字符串
(?P<group_name>) 爲匹配分組制定特定的組名
(?P=<group_name>) 引用特定組名的匹配字符串

首先,|和()的用法比較容易理解,例如咱們須要匹配多個郵箱的地址是否合法,例若有gmail郵箱、outlook郵箱,假定@前的字符數爲6到20個,此時能夠寫成:

1
2
3
4
5
6
7
>>> pa  =  re. compile ( '[\w]{6,20}@(gmail|outlook).com$' )
>>> ma  =  pa.match( 'bokeyuan@gmail.com' )
>>> ma.group()
'bokeyuan@gmail.com'
>>> ma  =  pa.match( 'bokeyuan@outlook.com' )
>>> ma.group()
'bokeyuan@outlookl.com'

後邊三個的用法根據下邊的例子進行說明:

1
2
3
4
5
6
7
8
9
10
>>>  str  =  '<code>python</code>'
>>> ma  =  re.match(r '<[\w]+>' str )
>>> ma.group()
'<code>'
>>> ma  =  re.match(r '<([\w]+>)[\w]+</\1' str )
>>> ma.group()
'<code>python</code>'
>>> ma  =  re.match(r '<(?P<group1>[\w]+>)[\w]+</(?P=group1)' str )
>>> ma.group()
'<code>python</code>'

其中,第一個例子就是對字符串‘<code>'進行匹配。咱們發現str中其實有兩部分是徹底相同的,就是都含有'code>'這個substring,因而能夠看第二個例子,咱們用()將([\w]+>)這部份內容括住時,這部分匹配的字符串就是'code>',([\w]+>)就是一個分組,沒有起名字的狀況下默認<number>爲1,所以在咱們須要在末尾再次引用到它的時候,就寫上 /1 便可。第三個例子與第二個例子的效果徹底相同,只不過爲了更加清楚的記住匹配分組的名字,咱們利用(?P<group_name>)這一語法功能,人爲的爲這個分組取了一個group1的名字,在最後又引用了這一分組。

 

4. 注意字符串中轉義字符的問題

上述例子中,出如今正則表達式前邊的r是原始字符串操做符,能夠寫爲r或者R:表示字符串內的全部字符都按原始意思解釋。

例如:‘c:\python\test.py’ 若是不加r,則計算機會將 \t 會變成轉義字符解釋;加上r之後,寫爲:r‘c:\python\test.py’,計算機就會直接輸出c:\python\test.py,不然要想輸出c:\python\test.py,必須將字符串寫爲‘c:\\python\\test.py’

 

2、介紹幾個re模塊中的經常使用函數

1. search(pattern, string, flags=0)函數

search函數功能:在字符串中查找匹配

例如:博客會記錄來訪者的數量,咱們經過正則匹配查找字符串中的數字:

1 str1 = 'number of visitors = 1000'
2 info = re.search(r'\d+', str1)  # 匹配字符串str1中的數字
3 print('訪客數量:', info)
4 print(info.group())  # 顯示匹配的內容

 固然,上述操做也能夠經過對字符串直接操做得到,例如:print('訪客數量:', str1.find('1000')) 。可是這樣存在一個問題,由於訪客數量實在不斷變化的,一旦1000這個數字增長,用字符串操做就難以實現。可是利用search函數就不存在這樣的問題。

 

2. findall(pattern, string, flags=0)函數

findall函數功能:找到匹配,並返回全部匹配內容的列表

例如,博客記錄了最近三天天天的訪客記錄,咱們須要將三天的訪客數量都查找出來,並計算總的訪客數量,此時用search函數沒法直接將三天的訪客數量同時提取,能夠採用findall函數:

1 str2 = 'day1=22, day2=34, day3=13'
2 info = re.findall(r'=[\d]+', str2)
3 print(info)
4 print('三天的訪客數量爲:', sum([int(x[1:]) for x in info]))

 

3. sub(pattern, repl, string, count=0, flags=0)函數

sub函數功能:將字符串中匹配正則表達式的部分替換爲其餘值。其中repl能夠是一個字符串,也能夠是一個函數。

當repl是一個字符串時,仍然以訪客記錄爲例,當增長一個訪客時,須要修改記錄中的數字:

1 str3 = 'number of visitors = 1000'
2 info = re.sub(r'[\d]+', '1001', str3)
3 print(info)  # 此時輸出結果爲 number of visitors = 1001

可是此時每次修改都必須手動輸入數字,顯然,對於這種隨時變化的數字來講,這種操做是不合理的。而sub函數的高明之處就是容許repl是一個函數。

當repl爲一個函數時,首先會在string中查找pattern的匹配,查找到的匹配是一個match對象,這個match對象就會被傳遞到repl這個函數中。上述例子能夠這樣實現:

複製代碼
1 # 首先,定義一個增長訪客數量的函數,函數的參數是一個match對象
2 def add_num(match):
3     val = match.group()
4     num = int(val) + 1
5     return str(num)
6 
7 str3 = 'number of visitors = 1000'
8 print('最新訪客數量:', re.sub(r'[\d]+', add_num, str3)) # 打印結果,最新訪客數量:number of visitors = 1001
複製代碼

 

4. split(pattern, string, maxsplit=0, flags=0)函數

split函數功能:根據匹配分割字符串,返回分割字符串組成的列表

1 str4 = 'day1=22, day2=34, day3=13'
2 print(re.split(r', ', str4))  # 打印出的內容爲 ['day1=22', 'day2=34', 'day3=13']
相關文章
相關標籤/搜索