1. 程式人生 > >Python正則表示式匹配反斜槓“\”

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核心程式設計》第二版,如有不恰當的地方,還望包容和指出,感謝。