Python學習(17)--正則表達式2

Python學習(17)--正則表達式2

(1)正則表達式的元字符轉義"\"

在上一節我們提到,正則表達式中當元字符^位於模式子串的開頭時,表示的是查找待匹配主串的開始是否是該模式子串,如果是則返回模式子串,否則返回空。下面有個例子我們來回顧下:

 

[python] view plain copy

  1. import re
  2. s1="^abc"
  3. print(re.findall(s1,"abcd"))
  4. print(re.findall(s1,"aa abcd"))

 

如上代碼正則表達式爲s1="^abc",用於匹配主串開頭是否爲"abc",如果是返回"abc",否則返回空。代碼打印結果如下:

在正則表達式中,有時候我們需要匹配的字符串中含有元字符,比如正則表達式中含有"^",而且"^"是正則表達式的首位字符,如下:

 

[python] view plain copy

  1. import re
  2. s1="^abc"
  3. print(re.findall(s1,"^abc ^abc ^abc"))

 

如上s1="^abc","^"位s1的首位,但是s1表示的含義是查詢主串的開始字符串是否是"abc",而不是查詢主串中是否含有模式子串"^abc"。代碼打印結果如下:

 

那麼模式子串如果有元字符"^",如果想匹配字符"^"怎麼辦呢?答案就是利用轉義字符"\",把"^"轉義成一個普通字符。如下:

 

[python] view plain copy

  1. import re
  2. s1="\^abc"
  3. print(re.findall(s1,"^abc ^abc ^abc"))

 

s1="\^abc","^"被轉義成一個普通字符"^",這時模式子串爲"^abc",即匹配主串中是否含有字符串"^abc",打印結果如下:

使用轉義字符可以方便的表示某些數據,例如\d表示的是一個整數。在上一節使用的是正則表達式[1-9]來匹配一個整數字符,其實一個整數字符的正則表達式也可以表示爲[\d],代碼如下:

 

[python] view plain copy

  1. import re
  2. s4="x[\d]x"
  3. print(re.findall(s4,"x1x x2x x3x x4x"))

 

如上s4="x[\d]x",[\d]表示數字字符'1'-'9',s4可以匹配到的字符串爲"x1x","x2x"...代碼

打印結果如下:

\後加其他字符還可以表示不同的含義,如:\d,\D,\w,\W,\s,\S。具體表示的含義如下圖所示:

(2)重複{}

正則表達式中的元字符{}表示{}前一個字符重複的次數,{}中只含有一個數時表示的是字符重複的次數,比如{8}表示{8}前面的一個字符重複8次。{}也可以表示一個重複的範圍,比如{1,6}表示{1,6}前的一個字符重複1至6次。形如{,y}表示重複次數的區間爲[0,y],{x,}表示重複次數的區間爲[x,∞]。

下面以一個電話號碼的正則表達式匹配爲例,假設一個電話號碼前3位爲區號,後8位爲電話號碼,區號與電話號碼之間用符號"-"隔開。如下的正則表達式可以匹配電話號碼

,代碼例子如下:

 

[python] view plain copy

  1. import re
  2. s5="\d\d\d-\d\d\d\d\d\d\d\d"
  3. print(re.findall(s5,"010-87654321"))
  4. print(re.findall(s5,"010-8765432"))

 

如上s5匹配的模式子串爲前3個字符爲數字,後8個字符爲數字,中間使用字符"-"隔開。匹配字符串得到的結果如下:

雖然以上匹配得到的結果是正確的,但是書寫的正則表達式比較麻煩,而且可讀性也不強。使用重複元字符{}可以有效解決這個問題,如下代碼:

 

[python] view plain copy

  1. import re
  2. s6="\d{3}-\d{8}"
  3. print(re.findall(s6,"010-"))
  4. print(re.findall(s6,"010-87654321"))
  5. print(re.findall(s6,"010-8765432"))

 

如上s6="\d{3}-\d{8}","\d{3}"表示數字字符重複3次,也就是模式子串以3個數字字符作爲開始字符串,"\d{8}"表示模式子串以8個數字字符作爲結尾字符串,兩個字符串用字符"-"隔開。匹配結果如下所示:

當在正則表達式中使用{}的形式爲{x,y}時,表示重複次數區間爲[x,y]。如{1,3}爲重複次數爲區間[1,3]中的任意一個整數。當在主串中進行匹配時,如果字符重複的次數大於y,則會在匹配長度最長的字符串之後,對主串分割後再匹配。代碼如下:

 

[python] view plain copy

  1. import re
  2. s13="a{1,3}"
  3. print(re.findall(s13,"b"))
  4. print(re.findall(s13,"a"))
  5. print(re.findall(s13,"aa"))
  6. print(re.findall(s13,"aaa"))
  7. print(re.findall(s13,"aaaa"))

 

如上s13="a{1,3}",能匹配的最長模式子串爲"aaa",當在主串"aaaa"中匹配時,匹配到最長模式子串爲"aaa",然後把主串"aaaa"分割成"aaa"和"a"後,再使用正則表達式s13對"a"進行匹配,並將所有匹配得到的結果封裝在列表中返回。代碼打印結果如下:

(3)元字符*

元字符*在正則表達式中使用,表示的是*前的一個字符重複次數爲0次到無窮次,重複次數區間爲[0,∞],相當於{0,}。代碼如下:

 

[python] view plain copy

  1. import re
  2. s7="ab*"
  3. print(re.findall(s7,"a"))
  4. print(re.findall(s7,"ab"))
  5. print(re.findall(s7,"abbbbbb"))

 

如上所示,s7="ab*",*前的一個字符爲"b",則"b"在模式子串中重複的次數可以爲0到∞次,即s7可以匹配到的字符串爲"a","ab","abbb"...代碼打印結果如下:

(4)元字符+

在正則表達式中,元字符+與*唯一的不同就是,+在正則表達式中前的一個字符重複的次數至少1次,如正則表達式"abc+",+前的一個字符"c"在匹配的字符串中重複的次數至少一次,重複次數的區間爲[1,∞],相當於{1,}。可匹配到的模式子串如"abc","abcc","abccc"...而"ab"是匹配不到的。代碼例子如下:

 

[python] view plain copy

  1. import re
  2. s8="ab+"
  3. print(re.findall(s8,"a"))
  4. print(re.findall(s8,"ab"))
  5. print(re.findall(s8,"abbbbb"))

 

如上s8="ab+",元字符"+"前的一個字符爲"b",表示"b"在可匹配字符串中可重複出現的次數爲1到無窮次,例如,正則表達式s8可匹配的字符串有"ab","abb"等等。代碼打印結果如下:

(5)元字符?

在正則表達式中使用元字符?,表示的含義爲?前的一個字符重複的次數爲1次或者0次,重複次數的區間爲[0,1],相當於{0,1}。如下例子:

 

[python] view plain copy

  1. import re
  2. s11="ab?"
  3. print(re.findall(s11,"a"))
  4. print(re.findall(s11,"ab"))
  5. print(re.findall(s11,"abbb"))

 

如上例子,s11="ab?",元字符?前的字符爲"b",在可匹配到的模式子串中"b"可以出現的次數爲0或者1次,即可匹配到的模式子串爲"a"和"ab",代碼打印結果如下:

(6)正則表達式的貪婪匹配和非貪婪匹配

在寫正則表達式時,我們可以通過元字符?來控制模式子串的匹配是貪婪匹配或者非貪婪匹配。所謂貪婪匹配就是將模式子串匹配的長度最大化,所謂非貪婪匹配就是將模式子串匹配的長度最小化。例如對於正則表達式"ab+",可以匹配到的模式子串長度最小的爲"ab",最長的爲"abbbb...",而貪婪匹配就是匹配在主串中能夠匹配到的最長的子串,非貪婪匹配就是匹配在主串中匹配最短的模式子串。代碼例子如下:

 

[python] view plain copy

  1. import re
  2. s11="ab+"
  3. print(re.findall(s11,"ab"))
  4. print(re.findall(s11,"abbbbbb"))
  5. s12="ab+?"
  6. print(re.findall(s12,"ab"))
  7. print(re.findall(s12,"abbbbbb"))

 

如上S11="ab+",是一種貪婪匹配,即會匹配主串中長度最長子串,如"abbbbbb",使用正則表達式s11時在主串可匹配到的最長子串爲"abbbbbb";而s12="ab+?",是一種非貪婪匹配,即匹配最短的模式子串,即"ab"。代碼打印結果如下:

下一節,我們將繼續介紹正則表達式,敬請期待.北工大菜鳥與你一起努力,謝謝大家。

原文地址http://www.bieryun.com/2351.html