什麼是正則表達式
正則表達式:是一組特殊的字符序列,又稱爲規則表達式,它能方便你檢查一個字符串是否與某種模式匹配。一般用來檢索和替換那些符合某些模式的文本。python中的re模塊,實現了所有的正則表達式的功能,接下來將會對其進行詳細的講解。python
python 正則表達式的方法
python的re模塊,提供了不少正則表達式的用法,接下來就對其re提供的方法,來進行正則表達式的操做。正則表達式
- re.compile()
# re.compile(pattern, flags=0) # 給定一個正則表達式 pattern,指定使用的模式 flags 默認爲0 即不使用任何模式,而後會返回一個 SRE_Pattern(re 內置對象用法)對象 # 表達式能夠不進行編譯,也能夠進行匹配,可是若在大量使用正則時,能夠先對其編譯,由於編譯須要時間,在正則的使用時編譯事後就能夠 # 複用而無需從新編譯,能夠提升運行效率
# 例如 key = '121aaa111' pattern = re.compile(r'\d+') print pattern # 輸出結果返回一個對象: <_sre.SRE_Pattern object at 0x0000000002444588> value = re.search(pattern, key).group() value2 = re.search(r'\d+', key).group() print value # 121 print value2 # 121
# re.compile 的返回值對象,擁有和re模塊的全部方法,除compile ''' 例如: key = '123fdd' pattern = re.compile('\d+') pattern.findall(key) 等於 re.findall(pattern, key) pattern.findall() 會把pattern對象自己當作第一個參數傳入 '''
2. re.findall()緩存
# findall(pattern, string, flags=0) # 參數 pattern 爲正則表達式, string 爲待操做字符串, flags 爲所用模式,函數做用爲在待操做字符串中尋找全部匹配正則表達式的字串, # 返回一個列表,若是沒有匹配到任何子串,返回一個空列表
key = '''first line second line third line''' # compile 預編譯後使用 findall pattern = re.compile("\w+") print re.findall(pattern, key) # ['first', 'line', 'second', 'line', 'third', 'line'] # 返回對象直接調用findall(key) print pattern.findall(key) # ['first', 'line', 'second', 'line', 'third', 'line']
3.re.search()函數
# re.search(pattern, string, flags=0) # 使用指定正則去待操做字符串中尋找能夠匹配的子串, 返回匹配上的第一個字串,而且再也不繼續找. 若是找不到返回none
key = '''first line second line third line''' pattern = re.compile("\w+") print pattern.search(key).group() # first print re.search(pattern, key).group() # first key = '''@@@ line second line third line''' pattern = re.compile("\w+") print pattern.search(key).group() # line print re.search(pattern, key).group() #line
4.re.match()spa
# re.match(pattern, string, flags=0) # 使用指定正則去待操做字符串中尋找能夠匹配的子串, 返回匹配上的第一個字串,而且再也不繼續找,須要注意的是 match 函數是從字符串開始處開始查找的, # 若是開始處不匹配,則再也不繼續尋找,返回值爲 一個 SRE_Match (re 內置對象用法) 對象,找不到時返回 None
key = '''first line second line third line''' pattern = re.compile("\w+") print pattern.match(key).group() # first print re.match(pattern, key).group() # first key = '''@@@ line second line third line''' pattern = re.compile("\w+") print pattern.match(key).group() # 報錯, 由於返回none因此沒法調用group方法,而報錯 print re.match(pattern, key).group() # 報錯
5. re.escape(pattern)code
# re.escape(pattern) # 轉義 若是你須要操做的文本中含有正則的元字符,你在寫正則的時候須要將元字符加上反斜扛 \ 去匹配自身, 而當這樣的字符不少時, # 寫出來的正則表達式就看起來很亂並且寫起來也挺麻煩的,這個時候你可使用這個函數, 這種狀況下,pattern裏面的元字符會徹底失去意義,用法是能夠幫助咱們轉義須要轉義的字符串,而後能夠將這些字符串進行拼接成新的正則
key = ".+\d123" pattern = re.escape(".+\d123") # 查看轉義後的字符 print pattern # '\.\+\\d123' 格式是字符串的形式 # 查看匹配到的結果 print re.findall(pattern, key) # ['.+\\d123']
6. re.finditer()對象
# re.finditer(pattern, string, flags=0) # 參數和做用與 findall 同樣,不一樣之處在於 findall 返回一個列表, finditer 返回一個迭代器, 並且迭代器每次返回的值並非字符串, # 而是一個 SRE_Match (re 內置對象用法) 對象,這個對象的具體用法見 match 函數
key = '''first line second line third line''' pattern = re.compile("\w+") print pattern.finditer(key) # 返回迭代器對象 print re.finditer(pattern, key) # 返回迭代器對象 for i in pattern.finditer(key): print i print i.group() # 元素用group進行取值
7. re.split()blog
# re.split(pattern, string, maxsplit=0, flags=0) # 參數 maxsplit 指定切分次數, 函數使用給定正則表達式尋找切分字符串位置,返回包含切分後子串的列表,若是匹配不到,則返回包含原字符串的一個列表
key = '''first 111 line second 222 line third 333 line''' # 按照數字切分 pattern = re.compile('\d+') print pattern.split(key, 1) # ['first ', ' line\nsecond 222 line\nthird 333 line'] print re.split('\d+', key) # ['first ', ' line\nsecond ', ' line\nthird ', ' line'] # \.+ 匹配不到 返回包含自身的列表 print re.split('\.+', key, 1) # ['first 111 line\nsecond 222 line\nthird 333 line'] # maxsplit 參數 print re.split('\d+', key, 1) # ['first ', ' line\nsecond 222 line\nthird 333 line']
8. re.sub()索引
# re.sub(pattern, repl, string, count=0, flags=0) # 替換函數,將正則表達式 pattern 匹配到的字符串替換爲 repl 指定的字符串, 參數 count 用於指定最大替換次數
key = "the sum of 7 and 9 is [7+9]." # 基本用法 將目標替換爲固定字符串 print re.sub('\[7\+9\]', '16', key) # the sum of 7 and 9 is 16. # # 高級用法 1 使用前面匹配的到的內容 \1 表明 pattern 中捕獲到的第一個分組的內容 print re.sub('\[(7)\+(9)\]', r'\2\1', key) # the sum of 7 and 9 is 97.
sub的特殊用法,用函數進行替換:字符串
key = "the sum of 7 and 9 is [7+9]." def replacement(m): p_str = m.group() if p_str == '7': return '77' if p_str == '9': return '99' return '' # 這個用法的形式是將全部匹配到的值,做爲參數傳入提供的函數中,每一個參數都執行一次該函數,也能夠在末尾加上匹配次數 print re.sub('\d', replacement, key) # the sum of 77 and 99 is [77+99].
9.re.purge()
# re.purge() 清空表達式緩存 直接使用清空便可
以上就是對re模塊經常使用的一些正則表達式的方法。
正則表達式的元字符
標準字符:是可以與「多種普通字符」匹配的字符串組合,以下所示
標準字符 | 含義 |
---|---|
\d | 匹配0-9中的任意一個數字,等效於[0-9] |
\D | 匹配非數字字符,等效於[^0-9] |
\w | 匹配任意一個字母、數字或下劃線,等效於[^A-Za-z0-9_] |
\W | 與任何非字母、數字或下劃線字符匹配,等效於[^A-Za-z0-9_] |
\s | 匹配任何空白字符,包括空格、製表符、換頁符,等效於 ?[\f\n\r\t\v] |
\S | 匹配任何非空白字符,等效於[^\f\n\r\t\v] |
\n | 匹配換行符 |
\r | 匹配一個回車符 |
\t | 匹配製表符 |
\v | 匹配垂直製表符 |
\f | 匹配換頁符 |
以下例子:
import re key = '''@132fjasldfj1231 aaa, bbb ''' pattern = re.compile(r'\d+') print pattern.search(key).group() # 132 print pattern.findall(key) # ['132', '1231'] pattern0 = re.compile(r'\D+') # @ print pattern0.search(key).group() # ['@', 'fjasldfj', '\n aaa,\n bbb\n'] print pattern0.findall(key) pattern1 = re.compile(r'\w+') print pattern1.search(key).group() # 132fjasldfj1231 print pattern1.findall(key) # ['132fjasldfj1231', 'aaa', 'bbb'] pattern2 = re.compile(r'\W+') print pattern2.search(key).group() # @ print pattern2.findall(key) # ['@', '\n ', ',\n ', '\n'] pattern3 = re.compile(r'\s+') print pattern3.search(key).group() # 輸出的是空 print pattern3.findall(key) # ['\n ', '\n ', '\n'] pattern4 = re.compile(r'\S+') print pattern4.search(key).group() # @132fjasldfj1231 print pattern4.findall(key) # ['@132fjasldfj1231', 'aaa,', 'bbb'] pattern5 = re.compile(r'\n+') print pattern5.search(key).group() # 輸出空 print pattern5.findall(key) # ['\n', '\n', '\n'] pattern6 = re.compile(r'\t+') print pattern6.search(key).group() # 報錯 print pattern6.findall(key) # []
特殊字符 | 含義 |
---|---|
\ | 轉義字符,將下一個字符標記爲一個特殊字符 |
^ | 匹配字符串開始的位置 |
$ | 匹配字符串結尾的位置 |
* | 零次或屢次匹配前面的字符或子表達式 |
+ | 一次或屢次匹配前面的字符或子表達式 |
? | 零次或一次匹配前面的字符或子表達式 |
. | 「點」 匹配除「\r\n」以外的任何單個字符 |
| | 或 |
[ ] | 字符集合 |
( ) | 分組,要匹配圓括號字符,請使用 「(」 ?或 「)」 |
import re key = """SelectSelect **)()*^aaaa1214301asjl$@#! aaa 111, ^$&*@&dfjsalfjl""" pattern = re.compile(r'[\w\*]+') # 對*進行轉義 print pattern.findall(key) # ['Select', '**', '*', 'aaaa1214301asjl', 'aaa', '111', '*', 'dfjsalfjl'] print pattern.search(key).group() # Select pattern1 = re.compile(r'^Select[\s+]') # 表示必須以Select開頭,若不是則返回None print pattern1.findall(key) # ['Select '] print pattern1.search(key).group() # Select pattern2 = re.compile(r'\w+l$') # 從最後開始匹配 print pattern2.findall(key) # ['dfjsalfjl'] print pattern2.search(key).group() # dfjsalfjl pattern3 = re.compile(r'\w') pattern31 = re.compile(r'\w+') pattern32 = re.compile(r'\w*') print pattern3.findall(key) #['S', 'e', 'l', 'e', 'c', 't', 'a', 'a', 'a' 。。。 print pattern3.search(key).group() # S print pattern31.findall(key) # ['Select', 'aaaa1214301asjl', 'aaa', '111', 'dfjsalfjl'] print pattern31.search(key).group() # Select print pattern32.findall(key) # ['Select', '', '', '', '', '', '', '', '', 'aaaa1214301asjl', '', 。。。 print pattern32.search(key).group() # Select
限定字符:指的是匹配字符的次數的限制
限定字符 | 含義 |
---|---|
* | 零次或屢次匹配前面的字符或子表達式 |
+ | 一次或屢次匹配前面的字符或子表達式 |
? | 零次或一次匹配前面的字符或子表達式 |
{n} | n是一個非負整數,匹配肯定的n次 |
{n,} | n是非負整數,至少匹配n次 |
{n,m} | n和m是非負整數,其中n<=m;匹配至少n次,至多m次 |
定位符:指的是從那個地方開始匹配,或是匹配的起始或開始的限定
定位字符 | 含義 |
---|---|
^ | 匹配字符串開始的位置,表示開始 |
$ | 匹配字符串結尾的位置,表示結尾 |
\b | 匹配一個單詞邊界 |
re模塊的匹配模式
修飾符 | 描述 |
---|---|
re.I | 使匹配對大小寫不敏感 |
re.L | 作本地化識別(locale-aware)匹配 |
re.M | 多行匹配,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內的全部字符 |
re.U | 根據Unicode字符集解析字符。這個標誌影響 \w, \W, \b, \B. |
re.X | 該標誌經過給予你更靈活的格式以便你將正則表達式寫得更易於理解 |
re模塊分組用法
(...) 分組,默認爲捕獲,即被分組的內容能夠被單獨取出,默認每一個分組有個索引,從 1 開始,按照"("的順序決定索引值
s= '123123asasas1212aaasss1' p=r'([a-zA-Z]*)(\d*)' pattern=re.compile(p) print pattern.findall(s) # [('', '123123'), ('asasas', '1212'), ('aaasss', '1'), ('', '')] print re.search(pattern,s).group() # 123123 print re.match(pattern,s).group() # 123123 #\D 匹配非數字,至關於 [^0-9] #\s 匹配任意空白字符, 至關於 [ \t\n\r\f\v] s=r'123123asasas 1212aaa sss 1' p=r'([a-zA-Z]*\s)(\d*)' pattern=re.compile(p) print pattern.findall(s) # # [('asasas ', '1212'), ('aaa ', ''), ('sss ', '1')] #\S 匹配非空白字符,至關於 [^ \t\n\r\f\v] s=r'123123asasas 1212aaa sss 1' p=r'(\S+)(\d*)' pattern=re.compile(p) print pattern.findall(s) # [('123123asasas', ''), ('1212aaa', ''), ('sss', ''), ('1', '')] #\w 匹配數字、字母、下劃線中任意一個字符, 至關於 [a-zA-Z0-9_] s=r'123123asasas _12_ 1212aaa sss 1' p=r'(\w+)(\w+)' pattern=re.compile(p) print pattern.findall(s) # [('123123asasa', 's'), ('_12', '_'), ('1212aa', 'a'), ('ss', 's')] #\W 匹配非數字、字母、下劃線中的任意字符,至關於 [^a-zA-Z0-9_] s=r'12738647@qq.com//@' p=r'(\W+)qq(\W+)com(\W+)' pattern=re.compile(p) print pattern.findall(s) # [('@', '.', '//@')] #\b 匹配位於單詞開始或結束位置的空字符串,表示字母數字與非字母數字的邊界,非字母數字與字母數字的邊界 s=r'absd @bsc //bsc@ 1234' p=r'(\b\w+\b)' pattern=re.compile(p) print pattern.findall(s) # ['absd', 'bsc', 'bsc', '1234'] #\B 表示字母數字與字母數字的邊界,非字母數字與非字母數字的邊界 s=r' @absd @bsc ///bs___adc 1234@qq.com' p=r'(\B.+\B)' pattern=re.compile(p) print pattern.findall(s) # [' @absd @bsc ///bs___adc 1234@qq.co']
re模塊環視用法
環視還有其餘的名字,例如 界定、斷言、預搜索等,叫法不一。
環視是一種特殊的正則語法,它匹配的不是字符串,而是 位置,其實就是使用正則來講明這個位置的左右應該是什麼或者應該不是什麼,而後去尋找這個位置。
環視的語法有四種,見第一小節元字符,基本用法以下:
s = 'Hello, Mr.Gumby : 2016/10/26 Hello,r.Gumby: 2016/10/26' # 不加環視限定 print re.compile("(?P<name>\w+\.\w+)").findall(s) # ['Mr.Gumby', 'r.Gumby'] # 環視表達式所在位置 左邊爲 "Hello, " print re.compile("(?<=Hello, )(?P<name>\w+\.\w+)").findall(s) # ['Mr.Gumby'] # 環視表達式所在位置 左邊不爲 "," print re.compile("(?<!,)(?P<name>\w+\.\w+)").findall(s) # ['Mr.Gumby'] # 環視表達式所在位置 右邊爲 "M" print re.compile("(?=M)(?P<name>\w+\.\w+)").findall(s) # ['Mr.Gumby'] # 環視表達式所在位置 右邊不爲 r print re.compile("(?!r)(?P<name>\w+\.\w+)").findall(s) # ['Mr.Gumby']