筆記部分
總結得比較好的Python核心編程——第1章 正則表達式 by RealEmperor
問題部分
問題
假定我們擁有另一個特殊字符,它僅 僅包含字母“x”和“y”,我們此時僅僅想要這樣限定字符串:兩字母的字符串必須由一 個字母跟着另一個字母。換句話說,你不能同時擁有兩個相同的字母;要麼由“x”跟着“y”,要麼相反。
>>> bool(re.search(r'(?:(x)|y)(?(1)y|x)', 'xy')) #True
>>> bool(re.search(r'(?:(x)|y)(?(1)y|x)', 'xx')) #False
爲什麼上述的正則能且僅能匹配‘xy’或‘yx’ ?
相關知識
正則表達式:
表 示 法 | 描述 |
---|---|
(…) | 匹配封閉的正則表達式,然後另存爲子組 |
(?:…) | 表示一個匹配不用保存的分組(功能與(…)類似,但分組不同) |
((?id/name)Y|N) | 如果分組所提供的id或name(名稱)存在,就返回正則表達式的條件匹配Y,如果不存在就返回N;|N是可選項 |
bool類型判斷:
類型 | True or False 判定 |
---|---|
None | False |
任意數值類型0,如:0,0.0,0j. | False |
任意空序列,如:’’, (), []. | False |
任意空字典mapping,如:{} | False |
用戶自定義類中,定義了 _bool_() 或 _len_()返回0或False | False |
其他 | True |
實例驗證
?:的作用域,整個括號裏面的
>>> bool(re.search(r'(?:y|(x))(?(1)y|x)', test_str)) #True,當test_str等於‘xy’或'yx'
>>> bool(re.search(r'(?:(x)|y)(?(1)y|x)', test_str)) #False,當test_str 不等於'xy' 且不等於'yx'
()的編號順序
>>> re.search('(a|(b))','ba').groups() # ('b', 'b') , 第一個b指的是外層匹配的((b)),第二個b指的是內層的(b)
>>> re.search('(?:a|(b))','ba').groups() # ('b',), 最外層的分組沒有保留
>>> re.search('(?:a|(b))','ab').groups() # (None,), 匹配到了a,但是分組結果不保留,bool(re.search('(?:a|(b))','ab'))結果爲True
>>> re.search('(a|(b))','ab').groups() # ('a', None) ,匹配了第一個a,(b)不再匹配,因此爲None
>>> re.search('(a(b(c)))','abc').groups() # ('a', 'bc', 'c') ,匹配的序號按左括號出現的順序
>>> re.search('a|(b)','ab').groups() #
解釋 bool(re.search(r’(?:y|(x))(?(1)y|x)’, test_str))
- 輸入test_str=‘xy’,(?:y|(x))匹配x,保留分組(x, ),?(1)爲True,選擇匹配y, 匹配
- 輸入test_str=‘yx’ ,(?:y|(x))匹配y,不保留分組, ?(1)爲False,選擇匹配x,匹配
- 輸入test_str=‘xx’, (?:y|(x))匹配x,保留分組(x, ),?(1)爲True,選擇匹配y, 不匹配
- 輸入test_str=‘yy’, (?:y|(x))匹配y,不保留分組,?(1)爲False,選擇匹配x, 不匹配
總結
之所以不理解,一個是概念不清晰,(…)分組的概念,(?:…)匹配不保留分組, 以及python的bool函數的返回值。