在python中使用正則表達式 1.轉義符 正則表達式中的轉義: '\('表示匹配小括號 [()+*/?&.] 在字符組中一些特殊的字符會現出原形 所有的\s\d\w\S\D\W\n\t都表示他原本的意義 [-]只有寫在字符組的首位的時候表示普通的減號 寫在其它位置的時候表示范文[1-9]如果就是想匹配減號[1\-9] Python中的轉義符 分析過程: '\n'#\是轉義符 賦予這個n一個特殊的意義 表示一個換行符 print('\\n') print(r'\n') 轉義:python '\\\\n' 正則 '\\n' 結論: r'\\n' r'\n' 在python中 2.re模塊 准備: flags有很多可選值: re.I(IGNORECASE)忽略大小寫,括號內是完整的寫法 re.M(MULTILINE)多行模式,改變^和$的行為 re.S(DOTALL)點可以匹配任意字符,包括換行符 re.L(LOCALE)做本地化識別的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境,不推薦使用 re.U(UNICODE) 使用\w \W \s \S \d \D使用取決於unicode定義的字符屬性。在python3中默認使用該flag re.X(VERBOSE)冗長模式,該模式下pattern字符串可以是多行的,忽略空白字符,並可以添加注釋 1)匹配方法 findall() search() mathc() (1)findall() def findall(pattern, string, flags=0): """Return a list of all non-overlapping matches in the string. If one or more capturing groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result.""" return _compile(pattern, flags).findall(string) 用法:所有的匹配結果都返回在一個列表中,如果沒有匹配上就返回一個空列表。 例子: import re res = re.findall(r'\w+', r'Jake@tom') print(res) 結果: ['Jake', 'tom'] (2)search() def search(pattern, string, flags=0): """Scan through string looking for a match to the pattern, returning a match object, or None if no match was found.""" return _compile(pattern, flags).search(string) 用法:返回第一個匹配到的對象,可以調用這個對象的 group()方法返回第一個匹配到的值。沒有匹配上返回None。 例子: import re res1 = re.search(r'\d+', r'222T333') print('search', res1) print(res1.group()) 結果: search <_sre.SRE_Match object; span=(0, 3), match='222'> 222 (3)match() def match(pattern, string, flags=0): """Try to apply the pattern at the start of the string, returning a match object, or None if no match was found.""" return _compile(pattern, flags).match(string) 用法:和search用法一樣,唯一區別就是只在字符串開始匹配 例子: import re res2 = re.match(r'\d+', r'222T333')#與search區別就是只在字符串開始匹配 print('match', res2) print(res2.group()) 結果: match <_sre.SRE_Match object; span=(0, 3), match='222'> 222 2)切割和替換 sub() subn() split() (1)sub() def sub(pattern, repl, string, count=0, flags=0): """Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.""" return _compile(pattern, flags).sub(repl, string, count) 用法:根據(pattern)正則表達式規則將匹配好的字符串替換為新字符串(repl),string為目標串,count可以指定替換次數 例子: import re res = re.sub(r'\d+', 'SSS',r'222XXX333V3') print(res) 結果: SSSXXXSSSVSSS (2)subn() def subn(pattern, repl, string, count=0, flags=0): """Return a 2-tuple containing (new_string, number). new_string is the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in the source string by the replacement repl. number is the number of substitutions that were made. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.""" return _compile(pattern, flags).subn(repl, string, count) 用法:根據(pattern)正則表達式規則將匹配好的字符串替換為新字符串(repl),string為目標串,count可以指定替換次數. 返回的結果是元組,其中有替換結果和替換次數 例子: import re res = re.subn(r'\d+', 'SSS',r'222XXX333V3') print(res) 結果: ('SSSXXXSSSVSSS', 3) (3)split() def split(pattern, string, maxsplit=0, flags=0): """Split the source string by the occurrences of the pattern, returning a list containing the resulting substrings. If capturing parentheses are used in pattern, then the text of all groups in the pattern are also returned as part of the resulting list. If maxsplit is nonzero, at most maxsplit splits occur, and the remainder of the string is returned as the final element of the list.""" return _compile(pattern, flags).split(string, maxsplit) 用法:按照正則表達式匹配好的字符串去切割目標字符串,匹配對個結果會先拿第一個結果切割目標串, 切割完后拿第二個結果切割這兩個字符串,以此類推。可以指定最大切割次數,返回一個列表。 例子: import re res = re.split(r'\d+', r'333FF444FF44') print(res) 結果: ['', 'FF', 'FF', ''] 3)進階 compile() finditer() (1)compile()*****時間效率 def compile(pattern, flags=0): "Compile a regular expression pattern, returning a pattern object." return _compile(pattern, flags) 用法:把正則表達式編譯為正則表達式對象 作用:節省時間,只有在多次使用某一個相同的正則表達式的時候,才會幫助我們提高效率。 例子: import re res = re.compile(r'\d+') print(res) 結果: re.compile('\\d+') (2)finditer()*****空間效率 def finditer(pattern, string, flags=0): """Return an iterator over all non-overlapping matches in the string. For each match, the iterator returns a match object. Empty matches are included in the result.""" return _compile(pattern, flags).finditer(string) 用法:根據正則表達式匹配字符串得到 一個迭代器,迭代器中每個元素都是一個對象,每個 對象都可通過 group()方法獲取對應的匹配值。 例子: import re res = re.compile(r'\d+') res = re.finditer(r'\d+', r'sss444ff333f') print(res) for r in res: print(r, '--------', r.group()) 結果: <callable_iterator object at 0x106f29668> <_sre.SRE_Match object; span=(3, 6), match='444'> -------- 444 <_sre.SRE_Match object; span=(8, 11), match='333'> -------- 333 3.正則表式進階(很重要) 分組與re模塊的組合使用 1)分組 () 與 findall() finditer() import re #findall會優先顯示分組中的內容,如果在第左半邊括號后加上?:就會取消分組優先 #(?:正則表達式) 取消優先 #如果有一個分組,那么就將匹配好的元素放到一個列表中,如果分組有兩個以上,那么這些元組組成一個元組存到列表中 res = re.findall(r'<(\w+)>', r'<a>我愛你中國</a><h1>親愛的母親</h1>') print(res) res = re.findall(r'<(?:\w+)>', r'<a>我愛你中國</a><h1>親愛的母親</h1>') print(res) 結果: ['a', 'h1'] ['<a>', '<h1>'] #不會優先分組中內容,可以通過group(分組名)來得到分組中的值 import re res = re.finditer(r'<(?:\w+)>', r'<a>我愛你中國</a><h1>親愛的母親</h1>') for i in res: print(i.group()) 結果: <a> <h1> 2)分組命名 分組與 search() #(?P<name>正則表達式)表示給分組起名字 #(?P=name)表示使用這個分組,這里匹配到的內容應該和分組中內容完全一致 <1> import re #search匹配的是第一次匹配好的值 #得到的結果可以使用結果.group()方法得到 #如果search與分組配合使用給group傳參數,第一個分組內容傳1的到第一分組內容,以此類推 #groups()函數的到一個所有分組的集合以元組形式返回 res = re.search(r'<(\w+)>(\w+)</(\w+)>', r'<a>hello</a>') print(res.group()) print(res.group(1)) print(res.group(2)) print(res.group(3)) print(res.groups()) 結果: <a>hello</a> a hello a ('a', 'hello', 'a') <2> import re res = re.search(r'<(?P<name>\w+)>\w+</(?P=name)>', r'<a>hello</a>') print(res.group('name')) print(res.group()) res = re.search(r'<(?P<name>\w+)>\w+</(?P=name)>', r'<a>hello</h1><a>hello</a>') print(res.group('name')) 結果: a <a>hello</a> a <3> import re res = re.search(r'<(?P<tt>\w+)>(?P<cc>\w+)</\w+>', r'<a>hello</h1><a>hello</a>') print(res.group('tt')) print(res.group('cc')) print(res.group()) 結果: a hello <a>hello</h1> 3)通過索引使用分組 #\1表示使用第一組,匹配到的內容必須和第一組中的內容完全一致。 import re #\1表示使用第一組,匹配到的內容必須和第一組中的內容完全一致。 res = re.search(r'<(\w+)>\w+</\1>', r'<a>hello</a>') print(res.group(1)) print(res.group()) 結果: a <a>hello</a> 4)分組與 split() 切割后的結果會保留分組內被切割的內容 import re ret = re.split('(\d+)','Tom18Jake20Json22') print(ret) 結果: ['Tom', '18', 'Jake', '20', 'Json', '22', ''] 總結: # 在python中使用正則表達式 # 轉義符 : 在正則中的轉義符 \ 在python中的轉義符 # re模塊 # findall search match # sub subn split # compile finditer # python中的正則表達式 # findall 會優先顯示分組中的內容,要想取消分組優先,(?:正則表達式) # split 遇到分組 會保留分組內被切掉的內容 # search 如果search中有分組的話,通過group(n)就能夠拿到group中的匹配的內容 # 正則表達式進階 # 分組命名 # (?P<name>正則表達式) 表示給分組起名字 # (?P=name)表示使用這個分組,這里匹配到的內容應該和分組中的內容完全相同 # 通過索引使用分組 # \1 表示使用第一組,匹配到的內容必須和第一個組中的內容完全相同