首頁 > 軟體

Python3中的re.findall()方法及re.compile()

2022-05-16 16:00:11

re.findall()方法及re.compile()

  • re.findall()在字串中找到正規表示式所匹配的所有子串,並返回一個列表;如果沒有找到匹配的,則返回空列表。

返回結果是列表型別,需要遍歷一下才能依次獲取每組內容。

findall(patern, string, flags=0)
  • pattern : 正則中的模式字串。
  • string : 要被查詢替換的原始字串。
  • flags : 標誌位,用於控制正規表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

1.例子

import re 
content = 'Hello 123456789 Word_This is just a test 666 Test'
results = re.findall('d+', content)    
 
print(results)
for result in results:
    print(result)

結果:

['123456789', '666']
123456789
666
 
Process finished with exit code 0

注意利用re.findall()函數沒有group()和groups(),因為其返回結果是一個列表。

2.re.compile()方法

  • re.compile()方法可以將正則字串編譯成正規表示式物件,以便在後面的匹配中複用。
re.compile(pattern[, flags])

re.compile()中可以傳入忽略換行等匹配模式,這樣在search()、findall()方法中就不需要額外傳入了。

因此,re.findall()方法有2種表達方式:

import re
 
content = 'one1two22three333four4444'
pattern = re.compile(r'd+')
print('===方法1:===')
result1 = re.findall(pattern, content)
print(result1)
 
print('===方法2===')
result2 = pattern.findall(content)
print(result2)

結果:

===方法1:===
['1', '22', '333', '4444']
===方法2===
['1', '22', '333', '4444']
 
Process finished with exit code 0

3.在使用findall()方法時的“坑”

注意正規表示式中括號()的使用

(1)正規表示式中當沒有括號時,正常匹配:

import re 
 
str1 = '2345  3456  4567  5678  6789'
pattern_1 = re.compile('w+s+w+') # w 表示匹配包括下劃線的任何單詞字元,等價於[A-Za-z0-9_]
print(pattern_1.findall(str1))

結果:

['2345  3456', '4567  5678']
 
Process finished with exit code 0

(2)正規表示式中有一個括號時,其輸出的內容就是括號匹配到的內容,而不是整個表示式所匹配到的結果:

import re
 
str1 = '2345  3456  4567  5678  6789'
pattern_1 = re.compile('(w+)s+w+') # w 表示匹配包括下劃線的任何單詞字元,等價於[A-Za-z0-9_]
print(pattern_1.findall(str1))

結果:

['2345', '4567']
 
Process finished with exit code 0

整個正規表示式執行了,只不過只輸出括號匹配到的內容,即輸出的是第一個 (w+) 匹配到的內容:

在第一次匹配時跟上述沒有括號時一樣,匹配到"2345 3456",只不過只輸出(/w+)匹配到的結果 即"2345";

第二次匹配同理,從"4567" 開始,匹配到"4567  5678",但是還是隻是輸出(/w+)匹配到的結果 即"4567"。

(3)當正規表示式中有兩個括號時,其輸出是一個list 中包含2個 tuple:

import re
 
str1 = '2345  3456  4567  5678  6789'
pattern_1 = re.compile('((w+)s+w+)') # w 表示匹配包括下劃線的任何單詞字元,等價於[A-Za-z0-9_]
print(pattern_1.findall(str1))

結果:

[('2345  3456', '2345'), ('4567  5678', '4567')]
 
Process finished with exit code 0

從輸出的結果可以看出,結果中包含兩個元組,每一個元組中有兩個字串。

第一個元組是第一次匹配的結果,其中的第一個字串 "2345 3456" 是正規表示式最外面的括號

  • ((w+)s+w+)

匹配輸出的結果;

第一個元組中的第二個字串 "2345"是正規表示式裡面括號

  • (w+)

匹配輸出的結果 ;

第二個元組是第二次匹配的結果,匹配原理與第一次匹配相同。

正規表示式findall函數問題

在寫正規表示式的時候總會遇到不少的問題, 特別是在表示式有多個元組的時候。下面看下re模組下的findall()函數和多個表示式元組相遇的時候會出現什麼樣的坑。

程式碼如下:    

import re
str="a b c d"
regex0=re.compile("((w )s w )")
print(regex0.findall(str))
regex1=re.compile("(w )s w ")
print(regex1.findall(str))
regex2=re.compile("w s w ")
print(regex2.findall(str))

結果:    

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

可能結果有點意外,下面解釋一下

  • 第一個正規表示式中是帶有2個括號的,我們可以看到其輸出是一個list 中包含2個 tuple
  • 第二個正規表示式中帶有1個括號,其輸出的內容就是括號匹配到的內容,而不是整個表示式所匹配到的結果。
  • 第三個正規表示式中不帶有括號,其輸出的內容就是整個表示式所匹配到的內容。

結論:findall()返回的是括號所匹配到的結果(如regex1),多個括號就會返回多個括號分別匹配到的結果(如regex),如果沒有括號就返回就返回整條語句所匹配到的結果(如regex2)。所以在提取資料的時候就需要注意這個坑。

實際上是由其並不是python特有的,這是 正則 所特有的 , 任何一門高階語言使用正則都滿足這個特點:有括號時只能匹配到括號中的內容,沒有括號【相當於在最外層增加了一個括號】。在正則裡面 “()” 代表的是分組的意思,一個括號代表一個分組,你只能匹配到"()"中的內容

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com