Python 正規表示式 Howto(3)

2021-06-12 18:10:11 字數 3684 閱讀 8192

為了方便閱讀,省略英文. 

另外乙個重複匹配字元是+,

可以匹配乙個或者是多個字元。請注意+和

*的區別,

*是匹配零個和多個

,+是匹配乙個或者是多個。來看個例子吧,

ca+t

可以匹配

cat(1個

a),caaat(3

個a),

但是不能匹配ct,

因為ct

中缺少a.

還有兩個重複匹配的限定符,乙個是問號

,?,可以匹配一次或者零次;?一般用來表示某些字元時可選的。比如在英語中分行符

-, home-?brew

可以匹配沒有分行符的單詞

homebrew

或者具有分行符的單詞

home-brew.

另外乙個重複匹配限定符就是

, 這是是乙個最靈活的限定符,上面講的一切的限定符都可以使用這個通用的重複限定符來表達。在這個表示式中,m

和n都是十進位制。這個表示式意思是,重複至少為

m次,至多為

n次。舉個例子來說,

a/b可以匹配

a/b, 

a//b

, 以及

a///b

. 但是不會匹配

ab,

原因是其沒有包含/字元

, 他也不能匹配

ab,

這個是因為含有四個/。

在這個強大的表示式中,我們可以生類m和

n。這樣的話,我們會使用預設值來代替我們省略的

m或者。假使我們省略

m的話我們會使用

0來代替。如果省略了

n,我們會使用語言的

int型別的上限,也就是

2^31

,這個值近似於無限。

喜歡偷懶的人也許注意到了,其實

*+?都可以使用

來表示。我們可以將其看成是

的偷懶的方式。跟*

是一樣的。跟+

是一樣的,跟?

是一樣的。鼓勵大家使用偷懶的方式*, 

+, 或者?

,原因是這些字元易讀,還有乙個原因是引擎對這些字元做了優化。

使用正規則表示式

現在我們來看一些簡單的正規表示式。我們首先想到的是我們如何使用正規表示式?不用擔心,

re模組已經幫我們實現了乙個

python

的正規表示式引擎。

re模組為了速度是使用

c語言編寫的。所以使用正規表示式比使用普通的字串操作可以得到更好的效率。為了更加進一步的提高效率,我們可以將模式串編譯成二進位制結構,然後再使用正則匹配。當你要匹配很多次的時候,這個還是挺必要的。

編譯模式串

被編譯的模式串可以用來匹配或者用來進行模式替換。

>>>

>>>

import

re

>>>p =re

.compile(

'ab*')

>>>

<_sre.sre_pattern object at 0x...>

re.compile()

也可以接受

flags

引數,

用來使能各種特殊的功能或者是使能各種語法變體。我們在稍後的文章中會一一介紹。現在我們先來看簡單的例子。

>>>p =re

.compile(

'ab*'

, re

.ignorecase) 傳入

re.compile()的re

引數是乙個標準的字串

. 正規表示式的模式表示式不是

python

的核心部分,他們也沒有特殊的語法,所以

re只能以標準字串的形式傳入. (

有些應用根本就不會使用正規表示式,所以我們也沒有必要將其納入語言的核心

) 為了將

re引入到

python

中,我們採用了跟

socket 和

zlib

一樣的策略,將其作為模組引入。

將模式使用字串表示保持了

python

簡潔的一貫風格,但是也帶來了很多的負面影響。我們會在下乙個章節中稍作介紹。

都是反斜槓惹的禍

前面已經提到過,正規表示式使用

('\'

)來制定一些特殊的形式或者讓一些特殊的匹配字元恢復他們的本來面貌。這個可能會個

python

中有些字串的真實字面值有衝突。(挺繞口的,看例子吧)

我們會在

latex

中經常使用

\section

,作為起始,來表示我們在編寫的**中寫了什麼東西。假使你要寫乙個模式來匹配

\section

, 你必須要使用反斜槓來解除反斜槓或者其他特殊字元的特殊功能。所以我們會把模式寫成

\\section

. 我們最終要傳給

re.compile()

的一定是

\\section

. 不要忘記,

python

同樣使用反斜槓,所以我們必須再次使用反斜槓來解除我們傳遞給

re.compile()

的兩個反斜槓。看具體的實現吧。

characters

stage

\section

我們匹配的字串

\\section

re.compile()

要使用的串

"\\\\section"

傳遞給re.compile()的串

簡而言之,為了匹配乙個反斜槓我們必須使用四個反斜槓

'\\\\'

,真正的串中需要兩個,為了構造這兩個反斜槓,我們必須繼續使用反斜槓。所以這幾造成了反斜槓風暴

. 在正規表示式中重複的使用反斜槓,會造成反斜槓風暴,導致串極難讀懂。(我來試著解釋一下原因,沒有經過驗證,純屬猜測:

re模組本身使用

c語言編寫,

c語言中同樣會使用兩個反斜槓來表示乙個反斜槓,這個挺容易理解的。我們難於理解的是為什麼還在需要兩個呢?

原因在於

python

的內建的字串型別給c的

char*

不能通用,這裡面存在一次轉換,在

python

將串傳遞給

c的我們必須構造乙個

c的字串。)

一種解決方案是是使用

python

的內建的原生串來表示正規表示式。以

'r'開頭的字串反斜槓不會做任何處理,比如

r"\n"

是兩個字元

'\'和

'n',

而"\n"

表示乙個換行符.在

python

中正規表示式我們強烈建議使用原生串書寫.

regular string

raw string

"ab*"

r"ab*"

"\\\\section"

r"\\section"

"\\w+\\s+\\1"

r"\w+\s+\1"

python正規表示式元字元 正規表示式

字元 描述將下乙個字元標記為乙個特殊字元 或乙個原義字元 或乙個 向後引用 或乙個八進位制轉義符。例如,n 匹配字元 n n 匹配乙個換行符。序列 匹配 而 則匹配 匹配輸入字串的開始位置。如果設定了 regexp 物件的 multiline 屬性,也匹配 n 或 r 之後的位置。匹配輸入字串的結束...

Python 正規表示式

1.在python中,所有和正規表示式相關的功能都包含在re模組中。2.字元 表示 字串的末尾 如 road 則表示 只有當 road 出現在乙個字串的尾部時才會匹配。3.字元 表示 字元中的開始 如 road 則表示 只有當 road 出現在乙個字串的頭部時才會匹配。4.利用re.sub函式對字串...

Python正規表示式

學習python自然而然就不得不面對正規表示式這個難題。當初在沒有學習python之前,自己也曾經嘗試著學習過正規表示式,但是那時候感覺很麻煩,很難懂,結果就是不了了之。但是現在學習python我用的書是 python基礎教程 第二版 這本書中對re模組的講解很簡單易懂,內容不多但起碼把人領進門了,...