PythonRegex,
Regex為進階的文字模式匹配、抽取、與/或文本形式的搜尋和替換功能提供了基礎。通過標準庫中的re模組來支援Regex。
常見的Regex符號和特殊字元
| 標記法 |
描述 |
Regex樣本 |
| 符號 |
|
|
| re1|re2 |
匹配Regexre1或者re2 |
foo|bat |
| . |
匹配任何字元(除了\n之外) |
b.b |
| ^ |
匹配字串的起始部分 |
^Dear |
| $ |
匹配字串的終止部分 |
/bin/*sh$ |
| * |
匹配0次或者多次前面出現的Regex |
[A-Za-z0-9]* |
| + |
匹配1次或者多次前面出現的Regex |
[a-z]+\.com |
| ? |
匹配0次或者1次前面出現的Regex |
goo? |
| {N} |
匹配N次前面出現的Regex |
[0-9]{3} |
| {M,N} |
匹配M-N次前面出現的Regex |
[0-9]{5,9} |
| [...] |
匹配來自字元集的任意單一字元 |
[aeiou] |
| [...x-y...] |
匹配x-y範圍內的任意單一字元 |
[0-9] |
| [^...] |
不匹配此字元集中出現的任何一個字元,包括某一範圍的字元(如果在此字元集中出現) |
[^aeiou] |
| (...) |
匹配封閉的Regex,然後另存新檔子組 |
([0-9]{3})? |
| 特殊字元 |
|
|
| \d |
匹配任何十進位數字,與[0-9]一致(\D與\d相反,不匹配任何非數值型的數字) |
data\d+.txt |
\w |
匹配任何字母數字字元,與[A-Za-z0-9]相同(與\W)相反 |
[A-Za-z]\w |
| \s |
匹配任何空白字元,與[\n\t\r\v\f]相同(與\S相反) |
of\she |
| \b |
匹配任何單詞邊界(\B相反) |
\bThe\b |
| \A(\Z) |
匹配字串的起始(結束) |
\ADear |
| |
|
|
如果問號緊跟在任何使用閉合操作符的匹配後面,它將直接要求Regex引擎匹配儘可能少的次數。
儘可能少的次數是什麼意思?當模式比對使用分組操作符時,Regex引擎將試圖“吸收”匹配該模式的儘可能多的字元。這通常被叫做貪婪匹配。問號要求Regex引擎去“偷懶”,如果有可能,就在當前的Regex中儘可能少地匹配字元,留下儘可能多的字元給後面的模式(如果存在)。
當使用Regex時,一對圓括弧可以實現以下任意一個(或者兩個)功能:
常見的Regex屬性
| 函數/方法 |
描述 |
| 僅僅是re模組 |
|
| compile |
使用任何可選的標記來編譯Regex的模式,然後返回一個Regex對象 |
| re模組函數和Regex對象的方法 |
|
| match |
嘗試使用帶有可選的標記的Regex的模式來匹配字串。如果匹配成功,就返回匹配對象;如果失敗,就返回None |
| search |
使用可標記搜尋字串中第一次出現的Regex。如果匹配成功,就返回匹配對象;如果失敗就返回None |
| findall |
尋找字串中所有(非重複)出現的Regex模式,並返回一個匹配對象 |
| finditer |
與findall()函數相同,但返回的不是一個列表,而是一個迭代器。對於每一次匹配,迭代器都返回一個匹配對象。 |
| split |
根據Regex的模式分隔字元,split函數將字串分割為列表,然後返回成功匹配的列表,分隔字元最多操作MAX次(預設分割所有匹配成功的位置)
|
| re模組函數和Regex對象的方法 |
|
| sub |
使用repl替換所有Regex的模式在字串中出現的位置,除非定義count,否則就將替換所有出現的位置 |
| purge() |
消除隱式編譯的Regex |
| 常用的匹配對象 |
|
| group |
返回整個匹配對象,或者編號為num的特定子組 |
| groups |
返回一個包含所有匹配子組的元祖(沒有成功,返回空元組) |
| groupdict |
返回一個包含所有匹配的命名子組的字典,所有的子組名稱作為字典的鍵 |
| 常用的模組屬性 |
|
| re.I |
不區分大小寫匹配 |
匹配對象以及group()和groups()方法
成功調用match()和search()返回的對象。
group()要麼返回整個匹配對象,要麼根據要求返回特定子組。groups()則僅返回一個包含唯一或者全部子組的元組。如果沒有子組的要求,那麼當group()仍然返回整個匹配時,groups()返回一個空元組。
使用match()方法匹配字串
match()函數試圖從字串的起始部分對模式進行匹配。
>>> re.match('foo','foo').group()'foo'>>> re.match('foo','food on match').group()'foo'>>> re.match('foo','fodo on match').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group‘
使用search()在一個字串中尋找模式(搜尋與匹配的對比)
search()和match()的工作機制完全一致,不同之處在於search會用它的字串參數,在任意位置對給定Regex模式搜尋第一次出現匹配的情況。
>>> re.match('foo','sea food').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> re.search('foo','sea food').group()'foo'
匹配多個字串
>>> bt = 'bat|bet|bit'>>> re.match(bt,'bat').group()'bat'>>> >>> re.match(bt,'bit').group()'bit'>>> >>> re.match(bt,'blt').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> re.match(bt,'he bit me').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> re.search(bt,'he bit me').group()'bit'
匹配任何單個字元
>>> anyend = '.end'>>> re.match(anyend,'bend').group()'bend'>>> >>> re.match(anyend,'end').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> re.match(anyend,'\nend').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> re.search('.end','The end.').group()' end'>>>
建立字元集[]
>>> re.match('[cr][23][dp][o2]','c3po').group()'c3po'>>> >>> re.match('[cr][23][dp][o2]','c2do').group()'c2do'>>> >>> re.match('r2d2|c3po','c2do').group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> re.match('r2d2|c3po','r2d2').group()'r2d2'>>>
重複、特殊字元以及分組
>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').group()'abc-123'>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').group(1)'abc'>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').group(2)'123'>>> re.match('(\w\w\w)-(\d\d\d)','abc-123').groups()('abc', '123')>>>
>>> m = re.match('ab','ab') #沒有子組>>> m.group() #完整匹配'ab'>>> m.groups() #所有子組>>> >>> m = re.match('(ab)','ab') >>> m.group()'ab'>>> m.groups()('ab',)>>> >>> m= re.match('(a)(b)','ab')>>> m.group()'ab'>>> m.group(1) # 子組1'a'>>> m.group(2) #子組2'b'>>> m.groups()('a', 'b')>>> >>> m = re.match('(a(b))','ab')>>> m.group()'ab'>>> m.group(1)'ab'>>> m.group(2)'b'>>> m.groups()('ab', 'b')>>>
匹配字串的起始和結尾以及單詞邊界
>>> m = re.search('^the','the end.')>>> m.group()'the'>>> >>> m = re.search('^the','end. the')>>> m.group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> m = re.search(r'\bthe','is the yes')>>> m.group()'the'>>> >>> m = re.search(r'\bthe','isthe yes') #有邊界>>> m.group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>> >>> m = re.search(r'\Bthe','isthe yes') #沒有邊界>>> m.group()'the'
使用findall()和finditer()尋找每一次出現的位置
findall()查詢字串中某個Regex模式全部的非重複出現的情況。總返回一個列表。
>>> re.findall('car','car')['car']>>> re.findall('car','scary')['car']>>> re.findall('car','carry the barcardi to car')['car', 'car', 'car']>>>
使用sub()和subn()搜尋與替換
兩者幾乎一樣,都是將某字串中所有匹配Regex的部分進行某種形式的替換。用來替換的部分通常是一個字串,但它也可能是一個函數,該函數返回一個用來替換的字串。subn()和sub()一樣,但是subn()還返回一個表示替換的總數,替換後的字串和表示替換總數的數字一樣一起作為一個擁有兩個元素的元組返回。
>>> re.sub('X','Mr.Smith','atten:X\n\nDear X,\n')'atten:Mr.Smith\n\nDear Mr.Smith,\n'>>> re.subn('X','Mr.Smith','atten:X\n\nDear X,\n')('atten:Mr.Smith\n\nDear Mr.Smith,\n', 2)>>> >>> re.sub('[ae]','X','abcdef')'XbcdXf'>>> re.subn('[ae]','X','abcdef')('XbcdXf', 2)>>>
在限定模式上使用split()分割字串
如果你不想為每次模式的出現都分割字串,就可以通過為max參數設定一個值(非零)來制定最大分割數。
如果給定分隔字元不是使用特殊符號來匹配多重模式的Regex,那麼re.split()與str.split()工作方式相同,例子如下
>>> re.split(':','str1:str2:str3')['str1', 'str2', 'str3']