標籤:port 正則 參考 one 提高效率 failed 編譯 運算式 res
PS:字串是編程時涉及到的最多的一種資料結構,對字串的操作幾乎無處不在。
Regex就是處理字串最好的方法。
參考原文
廖雪峰Regex
定義
Regex是一種用來匹配字串的強有力的武器,它的設計思想是用一種描述性的語言來給字串定義一個規則凡是符合規則的字串,我們就認為它“匹配”,否則,不匹配。
規則
\d 可以匹配一個數字,\w 可以匹配一個數字或字母,\s 可以匹配一個空格(包括TAB等空白符). 匹配任意一個字元,* 匹配任意個字元(包括0個),+ 匹配至少一個字元,?表示0個或1個字元,{n} 表示匹配n個字元, {n-m}表示匹配n到m個字元。
更精確地匹配,可以用 [ ] 表示範圍,如:[0-9a-zA-Z\_] 可以匹配一個數字、字母或者底線 ;[0-9a-zA-Z\_]+可以匹配至少由一個數字、字母或者底線組成的字串,比如‘a100‘,‘0_Z‘,‘Py3000‘等等; [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或底線開頭,後接任意個由一個數字、字母或者底線組成的字串,也就是Python合法的變數; [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精確地限制了變數的長度是1-20個字元(前面1個字元+後面最多19個字元)。A|B可以匹配A或B;^表示行的開頭,^\d表示以一個數字開頭,$ 表示行的結束,\d$表示必須以數字結尾。
Tip:要匹配
特殊字符如 ‘-‘就需要使用‘
\‘轉義。
re(regular expression)模組
OK,說清楚了基本的規則後,我們就來看看怎麼在Python中使用regex,Python中提供了re模組,該模組包含了
所有Regex的功能。
注意:要注意一點Python的字串本身也用 \ 轉義,所以我們應該使用r首碼來使我們不必考慮字串本身的轉義問題。
說了這麼多,我們來看看怎麼在Python匹配字串:
>>> import re>>> re.match(r‘^\d{3}\-\d{3,8}$‘, ‘010-12345‘)<_sre.SRE_Match object; span=(0, 9), match=‘010-12345‘>>>> re.match(r‘^\d{3}\-\d{3,8}$‘, ‘010 12345‘)>>>
match()方法匹配時,成功返回一個Match對象,失敗返回None。常見的判斷方法:
test = ‘使用者輸入的字串‘if re.match(r‘Regex‘, test): print(‘ok‘)else: print(‘failed‘)
切分字串
用Regex切分字串比用固定的字元更靈活,為什嗎?請看正常的切分代碼:
>>> ‘a b c‘.split(‘ ‘)[‘a‘, ‘b‘, ‘‘, ‘c‘]
無法識別連續的空格,此時想到Regex,來試試:
>>> re.split(r‘\s+‘, ‘a b c‘)[‘a‘, ‘b‘, ‘c‘]
加入, 試下:
>>> re.split(r‘[\s\,]+‘, ‘a,b,c ,d‘)[‘a‘, ‘b‘, ‘c‘, ‘d‘]
Tips:如果使用者輸入了一組標籤,記得用Regex來把不規範的輸入轉化成正確的數組。
分組
除了簡單地判斷是否匹配外,Regex還有提取子串的強大功能。用() 表示的就是要提取的分組,如:^(\d{3})-(\d{3,8})$分別定義了兩個分組,這就可以直接從匹配的字串中提取出區號和本地號碼:
>>> m = re.match(r‘^(\d{3})-(\d{3,8})$‘, ‘010-12345‘)>>> m<_sre.SRE_Match object; span=(0, 9), match=‘010-12345‘>>>> m.group(0)‘010-12345‘>>> m.group(1)‘010‘>>> m.group(2)‘12345
注意:group(0)永遠是原始字串,group(1),group(2)......表示第1,2.....個子串。
貪婪匹配
Regex預設是貪婪匹配,也就是匹配儘可能多的字元。如,匹配數字後面的0:
>>> re.match(r‘^(\d+)(0*)$‘, ‘102300‘).groups()(‘102300‘, ‘‘)
可見\d+採用貪婪匹配使後面的0*只能匹配Null 字元串了。
那麼怎麼讓\d+採用非貪婪匹配(儘可能少地匹配),讓後面的0*也能匹配到字元,加個?就可以了:
>>> re.match(r‘^(\d+?)(0*)$‘, ‘102300‘).groups()(‘1023‘, ‘00‘)
Tips:groups()所有分組後的子串,不包括原始字串。當我們在Python中使用Regex時,如果一個Regex要使用幾千次,我們就可以先行編譯該Regex,接下來就不需要編譯了,直接匹配,這樣可以提高效率。
PythonRegex