python正則表達式匹配之轉義符\陷阱

       python中的轉義就是通過轉義符號\對字符進行字面意思和字符特殊定義(如果有的話)之間的轉換,python中使用標準模塊re進行字符串的正則表達式匹配時,需要特別注意轉義符的使用,如果不瞭解正則表達式和字符串的轉義符,那麼很容易在使用正則表達式匹配時犯錯。

       在使用python的re模塊進行正則匹配時,關於轉義符需要注意的點有三處:1、正則表達式和字符串匹配的經歷過程;2、字符串轉義;3、正則表達式轉義。

1、正則表達式和字符串匹配過程

       當我們使用正則表達式字符串和被匹配字符串進行匹配時,實際上發生的過程如下圖所示。即對於正則表達式字符串,其首先會經過python對字符串對象的轉義,得到轉以後的字符串,然後進一步的,re會使用轉以後的字符串作爲正則表達式pattern對象;當然進一步匹配的時候,正則表達式自身也有轉義。對於被匹配的字符串,其也是經過字符串轉義後再進入正則表達式匹配的。

       因此,當我們要利用正則表達式進行匹配時,由於對於正則表達式的字符串轉義不是我們所需要的,因此我們可以直接使用原生字符串(即以r作爲開頭表示的字符串,比如r'raw_string')來寫正則表達式,這樣可以避免字符串轉義這個過程帶來的非預期結果。具體的,我們看如下例子。

import re

re.findall(r'\\','\\')
[out]: ['\\']   #這個結果可以說明對於被匹配字符串,是經過字符串轉以後匹配的,
                #因爲如果不轉義直接匹配,那麼被匹配的字符串爲'\\',正則轉義後的'\\'爲'\',
                #匹配後得到的結果將是['\','\'],其輸出的格式將是['\\','\\'],因爲'\'不是合法
                #的輸出對象,而是打印顯示結果


re.findall('\\.','\\k')
[out]: []

re.findall('\\.','as.s')
[out]: ['.']    #這兩個結果說明,對於正則表達式字符串,其是先經過字符串轉義,再經過正則轉義後
                #進行匹配的;因爲如果是直接正則轉義,那麼'\\.'匹配的是\加任意字符,所以對
                #'\\k'的匹配結果應該是['\\k'],但實際結果是[];而實際上先經過字符串轉義,得到\.,
                #再經過正則轉義,得到的就是原生的'.',因此對於'as.s'的匹配結果是['.']

2、字符串轉義

       對於字符串的轉義,如果是未預定義的轉義,或者說是一個單獨的轉義符\出現在字符串中,那麼其會被認爲是原生的\,但是爲了保證顯示的是\,會在對象輸出的時候自動輸出爲\\。如下所示。

s = 'ca\lm'
s
[out]: 'ca\\lm'

3、正則轉義

       對於正則表達式的轉義,如果\出現在了正則表達式中,但是其緊隨的符號是一個未定義的轉義,那麼對於python3.6之前的版本,單個的轉義符\會被自動忽略,但是在python3.6以及之後的版本,會發生報錯,即不允許未定義的轉義出現在正則表達式中,如果表達原生的\,需要\\進行轉義以表達原生的\;這樣報錯的機制是爲了給以後新加的轉義定義留空間,並保持代碼向後兼容,不然如果新的版本增加的新定義的轉義且舊版本不報錯,那麼舊代碼的正則表達式便不再適用了。

       因此,無論是字符串還是正則表達式,對於轉義符\的出現都要謹慎,對於原生反斜槓\的表示,記得進行\\轉義。

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