天天看點

Python正則運算符優先級re.findall('(.)*',

我們分别執行三個語句:

>>> re.findall('(.)*',"abc")         
['c', '']
>>> re.findall('(.*)',"abc")
['abc', '']
>>> re.findall('(.?)*',"abc")        
['', '']
>>>
      

可以看到三個執行結果完全不同,為什麼會這樣呢?老猿才開始沒弄明白。我們使用《​​妙用re.sub分析正規表達式解析比對過程​​》介紹的方法parsematch來分析一下這三個比對語句:

>>> parsematch('(.)*',"abc")           
第1次比對,比對情況:
    比對子串group(0): abc,位置為:(0, 3)
    比對子串group(1): c,位置為:(2, 3)
第2次比對,m.lastindex=None,比對情況:
    比對子串group(0): ,位置為:(3, 3)

可以看到“(.)*”是每次比對一個字母,再重複比對過程直到比對不到字母前停止,是以最後比對結果是字元“c”,在“c”之後是空字元串,由于*的原因也會比對成功。

>>> parsematch('(.*)',"abc")           
第1次比對,比對情況:
    比對子串group(0): abc,位置為:(0, 3)
    比對子串group(1): abc,位置為:(0, 3)
第2次比對,比對情況:
    比對子串group(0): ,位置為:(3, 3)
    比對子串group(1): ,位置為:(3, 3)

      

可以看到“(.*)”是第一次比對是比對所有字元"abc",比對到搜尋文本結束,第二次比對空字元串也是比對成功。

>>> parsematch('(.?)*',"abc")          
第1次比對,比對情況:
    比對子串group(0): abc,位置為:(0, 3)
    比對子串group(1): ,位置為:(3, 3)
第2次比對,比對情況:
    比對子串group(0): ,位置為:(3, 3)
    比對子串group(1): ,位置為:(3, 3)
>>>
      

可以看到“(.?)*”是每次比對0-1個字元,再執行星号指定的重複比對過程直到比對到“c”之後,由于“abc”[3:3]也能比對成功,是以最後比對結果是空串。

第2次比對“c”之後的空串開始,也是比對成功,是以又會比對到空串。

  1. 關于正規表達式優先級請參考《​​第11.26 Python正規表達式運算符優先級​​》;
  2. 正規表達式解析比對過程請參考《​​妙用re.sub分析正規表達式解析比對過程​​》;
  3. 貪婪模式和非貪婪模式的比對處理過程請參考《​​Python正規表達式W+和W*比對過程的深入分析​​》的相關分析。