RE模塊總結筆記

1.元字符

①方括號 [ ]:指定一個字符類用於存放你需要匹配的字符集合

 [abc] 會匹配字符 a,b 或 c;

 [a-c] 可以實現相同的功能

 [akm$] 會匹配任何字符 'a','k','m' 或 '$','$' 是一個元字符,但在方括號中它不表示特殊含義,它只匹配 '$'字符本身。

 [^5] 會匹配除了 '5' 之外的任何字符

②反斜槓\:如果在反斜槓後邊緊跟着一個元字符,那麼元字符的“特殊功能”也不會被觸發

例如需要匹配符號 [ 或 \,可以在它們前面加上一個反斜槓,以消除它們的特殊功能:\[,\\。

反斜槓後邊跟一些字符還可以表示特殊的意義

其中d:digit,s:space,w:word

它們可以包含在一個字符類中,並且一樣擁有特殊含義。例如 [\s,.] 是一個字符類,它將匹配任何空白字符(/s 的特殊含義),',' 或 '.'。

爲避免反斜槓冗餘的情況,對於原字符串,需要在其前面加上r。

③ * :用於指定前一個字符匹配零次或者多次。

例如 ca*t 將匹配 ct(0 個字符 a),cat(1 個字符 a),caaat(3 個字符 a),等等。

注:正則匹配是貪婪的,在開始時儘可能匹配多的內容,再進行回退。

如 a[bcd]*b匹配abcbd,首先匹配到a,然後在匹配 [bcd]*這一部分時,由於是儘可能多的匹配,會直接匹配到字符串結尾,

再進一步匹配b時,發現不滿足,就會回退字符串再次嘗試匹配b,這裏就是回退到d,匹配不成又回退到b,匹配成功,返回結果。

④ + :用於指定前一個字符匹配一次或者多次。

要特別注意 * 和 + 的區別:* 匹配的是零次或者多次,所以被重複的內容可能壓根兒不會出現;+ 至少需要出現一次。例如 ca+t 會匹配 cat 和 caaat,但不會匹配 ct。

⑤ ? :用於指定前一個字符匹配零次或者一次。

⑥ {m,n} :它的含義是前一個字符必須匹配 m 次到 n 次之間。

 {,n} 相當於 {0,n};如果是 {m,} 相當於 {m,+無窮};如果是 {n},則是重複前一個字符 n 次。

⑦ | :

或操作符,對兩個正則表達式進行或操作。如果 A 和 B 是正則表達式,A | B 會匹配 A 或 B 中出現的任何字符。爲了能夠更加合理的工作,| 的優先級非常低。例如 Fish|C 應該匹配 Fish 或 C,而不是匹配 Fis,然後一個 'h' 或 'C'。

⑧ ^ :

匹配字符串的起始位置。如果設置了 MULTILINE 標誌,就會變成匹配每一行的起始位置。在 MULTILINE 中,每當遇到換行符就會立刻進行匹配。
 

re.search('^From', 'From Here to Eternity')

#結果:<_sre.SRE_Match object; span=(0, 4), match='From'>

re.search('^From', 'Reciting From Memory')

#結果:None

⑨ $ :匹配字符串的結束位置,每當遇到換行符也會離開進行匹配。

⑩ \A,\Z:

只匹配字符串的起始位置。如果沒有設置 MULTILINE 標誌的時候(即re.M),\A 和 ^ 的功能是一樣的;但如果設置了 MULTILINE 標誌,則會有一些不同:\A 還是匹配字符串的起始位置,但 ^ 會對字符串中的每一行都進行匹配。

⑪\b:單詞邊界,這是一個只匹配單詞的開始和結尾的零寬斷言。“單詞”定義爲一個字母數字的序列,所以單詞的結束指的是空格或者非字母數字的字符。

  1. >>> p = re.compile(r'\bclass\b')
  2. >>> print(p.search('no class at all'))  
  3. <_sre.SRE_Match object; span=(3, 8), match='class'>
  4. >>> print(p.search('the declassified algorithm'))
  5. None
  6. >>> print(p.search('one subclass is'))
  7. None

⑫ ():分組符

  1. >> p = re.compile('(a(b)c)d')
  2. >>> m = p.match('abcd')
  3. >>> m.group(0)
  4. 'abcd'
  5. >>> m.group(1)
  6. 'abc'
  7. >>> m.group(2)
  8. 'b'
  9. >>> m.groups()
  10. ('abc', 'b')

⑬ \1,\2...:

\1 表示引用前邊成功匹配的序號爲 1 的子組。

  1. >>> p = re.compile(r'(\b\w+)\s+\1')
  2. >>> p.search('Paris in the the spring').group()
  3. 'the the'

 

2.方法

注意,由於方法可能會因無結果,後續使用group時可配合try使用,也可以利用if判斷是否有匹配對象返回。

使用過程:先進行compile編譯,再利用編譯後的變量調用函數。

如:

p = re.compile('[a-z]+')

result = p.match("aaa")

結果:

<_sre.SRE_Match object; span=(0, 5), match='aaa'>

返回的是一個匹配對象,而匹配對象還有對應的方法。

如果不使用編譯模式,也可以直接使用re的全局函數,如re.match(r'\s+', 'aa aa'),即第一個爲正則字符串,第二個爲匹配的字符串,當然,這種速度相對較慢。

3.匹配對象

4.re.

①re.X

 這個選項忽略規則表達式中的空白和註釋,並允許使用 ’#’ 來引導一個註釋。這樣可以讓你把規則寫得更美觀些。

rc = re.compile(r"""
# start a rule
/d+
# number
| 
[a-zA-Z]+
# word
""", re.X)
res = rc.match('aaaa')
# print(res)
print(res.group())

②re.I

忽略大小寫

③re.S

使得 . 可以匹配任何字符,包括換行符。如果不使用這個標誌,. 將匹配除了換行符的所有字符。

a = """sdfkhellolsdlfsdfiooefo:
877898989worldafdsf"""
b = re.findall('hello(.*?)world',a)
c = re.findall('hello(.*?)world',a,re.S)
print ('b is ' , b)
print ('c is ' , c)
 
 
# 輸出結果:
# b is  []
# c is  ['lsdlfsdfiooefo:\n877898989']

④re.A

使得 \w,\W,\b,\B,\s 和 \S 只匹配 ASCII 字符,而不匹配完整的 Unicode 字符。這個標誌僅對 Unicode 模式有意義,並忽略字節模式。

⑤re.L

LOCALE
使得 \w,\W,\b 和 \B 依賴當前的語言(區域)環境,而不是 Unicode 數據庫。

區域設置是 C 語言的一個功能,主要作用是消除不同語言之間的差異。例如你正在處理的是法文文本,你想使用 \w+ 來匹配單詞,但是 \w 只是匹配 [A-Za-z] 中的單詞,並不會匹配 'é' 或 '&#231;'。如果你的系統正確的設置了法語區域環境,那麼 C 語言的函數就會告訴程序 'é' 或 '&#231;' 也應該被認爲是一個字符。當編譯正則表達式的時候設置了 LOCALE 的標誌,\w+ 就可以識別法文了,但速度多少會受到影響。

⑥re.M

通常 ^ 只匹配字符串的開頭,而 $ 則匹配字符串的結尾。當這個標誌被設置的時候,^ 不僅匹配字符串的開頭,還匹配每一行的行首;& 不僅匹配字符串的結尾,還匹配每一行的行尾。

5.group與groups

m = re.search(r"([0-9])*", "123")
print(m.groups())
# 結果:('3',) 原因:[0-9]是一個字符,由於貪婪匹配,會盡可能匹配到最後的3

m = re.search(r"([0-9])*", "123")
print(m.group())
# 結果:123 返回整個匹配的字符串而非括號內的分組

6.非捕獲組和命名組

①非捕獲組

有時候只是需要用一個組來表示部分正則表達式,並不需要這個組去匹配任何東西,這時可以通過非捕獲組來明確表示意圖。非捕獲組的語法是 (?:...),這個 ... 你可以替換爲任何正則表達式。

m = re.search(r"1(?:[abc])+1", "1abc1") #注意養成良好的加r習慣
print(m.group())

②命名組

命名組的語法是 Python 特有的擴展語法:(?P<name>)。很明顯,< > 裏邊的 name 就是命名組的名字啦。命名組除了有一個名字標識之外,跟其他捕獲組是一樣的。

匹配對象的所有方法不僅可以處理那些由數字引用的捕獲組,還可以處理通過字符串引用的命名組。除了使用名字訪問,命名組仍然可以使用數字序號進行訪問:
 

  1. >>> p = re.compile(r'(?P<word>\b\w+\b)')
  2. >>> m = p.search( '(((( Lots of punctuation )))' )
  3. >>> m.group('word')
  4. 'Lots'
  5. >>> m.group(1)
  6. 'Lots'

7.擴展機制

①前向斷言(?=...)

前向肯定斷言。如果當前包含的正則表達式(這裏以 ... 表示)在當前位置成功匹配,則代表成功,否則失敗。一旦該部分正則表達式被匹配引擎嘗試過,就不會繼續進行匹配了;剩下的模式在此斷言開始的地方繼續嘗試。

②前向否定斷言(?!...)

前向否定斷言。這跟前向肯定斷言相反(不匹配則表示成功,匹配表示失敗)。

例如想匹配擴展名不是 bat 的文件,使用.*[.](?!bat$).*$即可

如果正則表達式 bat 在當前位置不匹配,嘗試剩下的部分正則表達式;如果 bat 匹配成功,整個正則表達式將會失敗(因爲是前向否定斷言嘛^_^)。(?!bat$) 末尾的 $ 是爲了確保可以正常匹配像 sample.batch 這種以 bat 開始的擴展名。

同樣,有了前向否定斷言,要同時排除 bat 和 exe 擴展名,也變得相當容易:

.*[.](?!bat$|exe$).*$

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章