Python正則表達式匹配反斜槓“\”


在學習Python正則式的過程中,有一個問題一直困擾我,如何去匹配一個反斜槓(即“\”)?



一、引入


在學習了Python特殊字符和原始字符串之後,我覺得答案應該是這樣的:

1)普通字符串:'\\'
2)原始字符串:r'\'
但事實上在提取諸如“3\8”反斜槓之前的數字時,我屢次碰壁,始終得不到結果。最終發現自己理解錯了,原來原始字符串和“正則轉義”沒有一點關係;下面詳細談一談。



二、字符串轉義


反斜槓,在Python中比較特殊,就是它可以用來構成一些特殊字符,比如“\n”表示換行,“\t”表示製表符。下面是使用“\n”的一行代碼:

print 'Hello\World\nPython'
結果爲:
“Hello\World
Python“

可以看到其中的“\n”已轉義爲換行符,而“\W”沒有發生轉義,原因是“\W”在“字符串轉義”中並不對應着特殊字符,沒有特殊含義。


如果現在要求變了,要求不對“\n”轉義爲換行,而是原封不動輸出爲“Hello\World\nPython”,該怎麼辦呢?


1)可以這樣寫“Hello\World\\nPython”,這樣輸出的時候,“字符串轉義”會把“\\”轉義爲“\”;

2)也可使用另一種方法:原始字符串;原始字符串(即r'...'):字符串中所有字符都直接按照字面意思來使用,不轉義特殊字符。

下面是使用原始字符串的代碼:

print r'Hello\World\nPython'
結果爲:
“Hello\World\nPython”
可以清楚看到,在使用原始字符串之後,“\n”未被轉義爲換行符,而是直接被輸出了。



三、正則轉義


好了,上面講的只是“字符串轉義”。同理,在正則表達式中也存在轉義,我們姑且先稱其爲“正則轉義”,其與“字符串轉義”完全不同,比如“\d”代表數字,“\s”代表空白符。下面我們先編寫開頭的例子,然後再分析。

提取“3\8”反斜槓之前的數字:

#!/usr/bin/env python
# coding=utf-8

import re

string = '3\8'
m = re.search('(\d+)\\\\', string)

if m is not None:
    print m.group(1)  # 結果爲:3

n = re.search(r'(\d+)\\', string)

if n is not None:
    print n.group(1)  # 結果爲:3

正則表達式字符串需要經過兩次轉義,這兩次分別是上面的“字符串轉義”和“正則轉義”,個人認爲“字符串轉義”一定先於“正則轉義”。

1)'\\\\'的過程:
先進行“字符串轉義”,前兩個反斜槓和後兩個反斜槓分別被轉義成了一個反斜槓;即“\\|\\”被轉成了“\|\”(“|”爲方便看清,請自動忽略)。“字符串轉義”後馬上進行“正則轉義”,“\\”被轉義爲了“\”,表示該正則式需要匹配一個反斜槓。

2)r'\\'的過程:
由於原始字符串中所有字符直接按照字面意思來使用,不轉義特殊字符,故不做“字符串轉義”,直接進入第二步“正則轉義”,在正則轉義中“\\”被轉義爲了“\”,表示該正則式需要匹配一個反斜槓。



四、結論


也就是說原始字符串(即r'...')與“正則轉義”毫無關係,原始字符串僅在“字符串轉義”中起作用,使字符串免去一次轉義。


也許有哥們會問,爲什麼“\d+\\\\”中的“\d+”即使沒用原始字符串,也沒出現什麼問題。那是因爲在做“字符串轉義”時,“\d”並不對應特殊字符,所以順利的留到了“正則轉義”時再處理,在“正則轉義”中其表示數字。



參考自《Python核心編程》第二版,如有不恰當的地方,還望包容和指出,感謝。


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