python正則表達式轉義注意事項

不管哪一種語言,在使用正則表達式的時候都避免不了一個問題,就是在匹配元字符的時候,須要對元字符進行轉義,讓python

正則表達式引擎將其當作普通字符來匹配。本文主要以python爲例,說明一下轉義中須要注意的問題。正則表達式

python的正則表達式中須要轉義的元字符有如下幾個:spa

    1. .
    2. ^
    3. $
    4. *
    5. +
    6. ?
    7. \\
    8. []
    9. |
    10. {}
    11. ()

python中對元字符的轉義使用雙反斜槓 \\ 來表示code

# 普通元字符的轉義
_string = '''
!@#$%^&
'''

# 不轉義
print re.findall('$', _string)
#>>> ['', '']

# 雙反斜槓轉義
print re.findall('\\$', _string)
#>>> ['$']

# 單反斜槓轉義
print re.findall('\$', _string)
#>>> ['$']

看上面的例子你們可能會發現,使用一個反斜槓 \ 也能夠達到轉義的效果,那爲何還要寫兩個呢?這得先搞清楚pythonblog

的字符串轉義(不是正則表達式轉義),python自己使用 \ 來轉義一些特殊字符,好比在字符串中加入引號的時候,爲了字符串

s = 'i\'m superman'
print s
#>>> i'm superman

防止和字符串自己的引號衝突,使用 \ 來轉義,通常狀況下這個也不會引發什麼問題,可是當你要使用 \ 來轉義 \ 的時候,get

就比較混亂了,好比咱們想要輸出一個 \ ,得寫兩個 \ ,不然會報語法錯誤,由於 \ 把後面的引號給轉義了,必須使用 \ string

# 錯誤寫法
# print '\'

# 正確寫法
print '\\'
#>>> \

# 原生字符串
print r'\\'
#>>> \\

將 \ 轉義一下使其不具有轉義功能,才能夠正確輸出,當使用原生字符串的時候,輸出顯示了兩個 \ ,看起來好像是寫幾個class

輸出幾個的樣子,若是這樣想的話,你能夠試一下,看能不能輸出奇數個 \。語法

先來講一下什麼是原生字符串,其實就是不進行特殊處理的字符串,所謂特殊處理,貌似就是針對轉義的,原生字符串

的誕生自己就是爲了解決轉義的時候寫了太多 \ 的問題,可是爲何使用了原生字符串仍然不能只輸出一個 \ 呢?其實這應

該算是一個bug,就是python的字符串不能以奇數個 \ 結尾,這樣的寫法會被認爲是將結尾的引號進行了轉義,致使語法錯

誤。具體能夠參考http://t.cn/RfolM3H

雖然原生字符串並非很完美,但它已經能夠幫咱們解決很大一部分問題了。好比當你想匹配 \ 的時候,原生字符串可

_string = '\\\\'
print _string
#>>> \\

# 字符串
for i in re.findall('\\\\', _string):
    print i
#>>> \
#>>> \

# 原生字符串
for i in re.findall(r'\\', _string):
    print i
#>>> \
#>>> \

以讓你少寫一半的 \ ,既節省代碼量,又增長可讀性。

說了這麼多也沒說爲何在寫正則表達式的時候一個 \ 也能夠起到轉義的做用。咱們先來分析一下一個字符串被正則表

達式引擎解析的過程,一共有4步:

    1. 首先正則表達式是一個python的字符串
    2. 字符串自己會先進行轉義處理
    3. 正則表達式引擎獲得處理以後的字符串後再對字符串進行正則表達式引擎本身的處理
    4. 開始匹配
# 字符串
# '\\\\'

# 通過python處理以後
# '\\'

# 正則表達式引擎接收到的
# '\\'

# 正則表達式引擎進行轉義處理後 能夠匹配到 \
# '\'

而當使用原生字符串的時候就變爲了3步

# 原生
# '\\'

# 再也不處理
# '\\'

# 正則表達式引擎接收到的
# '\\'

# 正則表達式引擎進行轉義處理
# '\' 

下面是最重要的一個,當使用一個 \ 轉義的時候,python會識別不了轉義序列,因而它就不作任何處理,直接傳給了

正則表達式引擎。這就解釋了爲何一個 \也能夠轉義。這個不算bug,雖然方便了使用,但會讓人很迷惑,有利有弊吧。

# 原生
# '\$'

# 識別不了 不進行處理
# '\$'

# 正則表達式引擎接收到的
# '\$'

# 正則表達式引擎進行轉義處理
# '$'

  下面舉幾個例子看一下

# 匹配 \d+
_string = 'i am \d+'

print re.findall('\\\\d\\+', _string)[0]
#>>> \d+

print re.findall(r'\\d\+', _string)[0]
#>>> \d+


# 匹配 []
_string = 'i am []'

print re.findall('\\[\\]', _string)[0]
#>>> []

print re.findall('\[\]', _string)[0]
#>>> []

print re.findall(r'\[\]', _string)[0]
#>>> []
相關文章
相關標籤/搜索