一、什么是正則表達式
正則表達式是一個特殊字符序列,一個字符串是否與我們所設定的這樣的字符序列相匹配。
應用:快速檢索文本、實現一些替換文本的操作
1、檢查一串數字是否是電話號碼
2、檢查一個字符串是否符合email
3、把一個文本里指定的單詞替換為另外一個單詞
例:
a='C|C++|Java|C#|Python|Javascript'
判斷a中是否包含Python
方法一:使用python內置方法
1) a.index('Python')>-1:
1 a='C|C++|Java|C#|Python|Javascript' 2 3 if a.index('Python')>-1: 4 print(True) 5 else: 6 print(False)
2)'Python' in a
1 a='C|C++|Java|C#|Python|Javascript' 2 if 'Python' in a: 3 print(True) 4 else: 5 print(False)
方法二:使用正則表達式
1 #coding=utf-8 2 import re 3 4 a='C|C++|Java|C#|Python|Javascript' 5 r=re.findall('Python',a) 6 print(r) 7 if len(r)>0: 8 print(u'字符串中包含Python') 9 else: 10 print(u'字符串中不包含Python')
以上例子中‘Python’是常量字符串,幾乎無意義。正則表達是的意義或者靈活即:規則
二、元字符與普通字符
a='C0C++7Java8C#9Python6Javascript'
查找a中所有的數字
1 #coding=utf-8 2 import re 3 a='C0C++7Java8C#9Python6Javascript' 4 r=re.findall('\d',a) 5 print(r)
總結:以上兩個例子中Python是普通字符,\d是元字符
正則表達式是由一系列的普通字符和元字符所組成的
正則表達式有很多,在實際工作中根據需要查找即可
三、字符集
字符集由[]括起來的一組字符組合,字符之間是或者的關系,^代表非,-代表范圍
字符集兩邊常常由普通字符構成,如‘a[cf]c’,普通字符a、c用來定界
1 #coding=utf-8 2 import re 3 ''' 4 字符集的使用 5 ''' 6 s = 'abc,acc,adc,aec,afc,ahc' 7 #查找s中,中間一個字符是c或f的單詞 8 r=re.findall('a[cf]c',s) 9 print(r) 10 11 #查找s中,中間一個字符不是c也不是f的單詞 12 r1=re.findall('a[^cf]c',s) 13 print(r1) 14 15 #查找s中,中間一個字符是c\d\e\f的單詞 16 r2=re.findall('a[c-f]c',s) 17 print(r2)
四、概括字符集
像\d、\D、\w這種具有高度概括的表達式,我們稱為概括字符集
1 #coding=utf-8 2 import re 3 ''' 4 概括字符集 5 ''' 6 a='Python 1111Java678php' 7 # r=re.findall('[0-9]',a) 8 r=re.findall('\d',a) 9 print(r)
五、數量詞
數量詞{}表示個數
如{3}表示3位;{3,6}表示最小3位,最大6位
1 #coding=utf-8 2 import re 3 ''' 4 數量詞{} 5 ''' 6 a='Python 1111\nJava678php' 7 #檢索所有單詞 8 # r=re.findall('[a-z]{3}',a) 9 #Python6位,Java4w位,php3位,所以取3到6位 10 r=re.findall('[a-zA-Z]{3,6}',a) 11 print(r)
六、貪婪與非貪婪
正則表達式默認是盡可能使用貪婪的匹配方式
非貪婪,后面加?
1 #coding=utf-8 2 import re 3 ''' 4 貪婪與非貪婪 5 ''' 6 a='Python 1111\nJava678php' 7 #貪婪方式匹配 8 r=re.findall('[a-zA-Z]{3,6}',a) 9 print(r) 10 #非貪婪方式匹配 11 r1=re.findall('[a-zA-Z]{3,6}?',a) 12 print(r1)
七、匹配0次1次無限次
1 #coding=utf-8 2 import re 3 a='pytho0python1pythonn2' 4 r=re.findall('python*',a) 5 r1=re.findall('python+',a) 6 r2=re.findall('python?',a) 7 print(r) 8 print(r1) 9 print(r2)
關於?
1、作為非貪婪匹配方式?前面是范圍
2、作為數量詞?前面是普通字符
1 #coding=utf-8 2 import re 3 a='pytho0python1pythonn2' 4 5 r=re.findall('python{1,2}',a) 6 r1=re.findall('python{1,2}?',a) 7 r2=re.findall('python?',a) 8 print(r) 9 print(r1) 10 print(r2)
八、邊界匹配符
例如:
1 #coding=utf-8 2 import re 3 4 # qq='100001' 5 # qq='101' 6 qq='100000001' 7 #檢查qq號碼是否符合4-8位數字 8 r=re.findall('\d{4,8}',qq) 9 print(r)
使用正則表達式'\d{4,8}'可以檢測出4-8位,小於4位,但是大於8位時,無法檢測,正確做法是使用首尾匹配
1 #coding=utf-8 2 import re 3 4 qq='100001' 5 # qq='101' 6 # qq='100000001' 7 #檢查qq號碼是否符合4-8位數字 8 r=re.findall('\d{4,8}$',qq) 9 print(r)
九、組
()小括號括起來的稱為一組
1 #coding=utf-8 2 import re 3 a='PythonPythonPythonPythonPython*%%php' 4 #檢測a中是否包含3個Python 5 r=re.findall('(Python){3}',a) 6 print(r)
十、匹配模式參數flag
findall(pattern, string, flags=0)方法中的第三個參數flags代表匹配模式
常用的匹配模式有
1 #coding=utf-8 2 import re 3 s = 'PythonC#\rJava\nPHP' 4 #使用re.I和re.S匹配模式,多個模式直接用|分隔 5 r=re.findall('c#',s,re.I|re.S) 6 print(r)
1 #coding=utf-8 2 import re 3 s = 'PythonC#\rJavaC#\nPHP' 4 #使用re.I和re.S匹配模式,多個模式直接用|分隔 5 r=re.findall('c#.{1}',s,re.I|re.S) 6 print(r)
十一、re.sub正則替換
1 #coding=utf-8 2 import re 3 4 s='PythonC#JavaC#phpC#' 5 r=re.sub('C#','GO',s,2) 6 r1=s.replace('C#','GO',1) 7 print(r) 8 print(r1)
其中‘GO’可以是函數
1 # coding=utf-8 2 import re 3 4 s = 'PythonC#JavaC#phpC#' 5 6 # r=re.sub('C#','GO',s,2) 7 def convert(value): 8 pass 9 r = re.sub('C#', convert, s) 10 print(r)
運行結果:
調用過程:
1)C#作為convert的參數
2)convert的返回作為re.sub()的參數,因無返回值所以替換后字符串中的C#消失了
打印value發現結果顯示的是對象且被調用了三次(因為設置了參數3)
要獲取值C#,需要用group()方法
1 # coding=utf-8 2 import re 3 4 s = 'PythonC#JavaC#phpC#' 5 6 def convert(value): 7 matched=value.group() 8 print(matched) 9 return '!!'+matched+'!!' 10 11 r = re.sub('C#', convert, s) 12 print(r)
12、把函數作為參數傳遞
上面convert是較為簡單的函數,實際中常常使用更為復雜的函數,作為sub()參數
1 # coding=utf-8 2 import re 3 4 s = 'A8C3711D86' 5 6 7 # 找出s中所有數字,大於6的替換為9,小於6的替換為0 8 def convert(value): 9 matched = value.group() 10 res = None 11 if int(matched) >= 6:#注意matched是str格式,需要轉成int格式 12 res = '9'#數字不能作為返回值,需要將int轉成str 13 else: 14 res = '0' 15 return res 16 17 18 r = re.sub('\d', convert, s) 19 print(r)
convert:你給我個字符串,我還你個字符串。至於中間變量value如何處理,不關心
思考:s中大於50的替換為100,小於50的替換為0
1 # coding=utf-8 2 import re 3 4 s = 'A8C3711D86' 5 6 7 # 找出s中所有數字,大於6的替換為9,小於6的替換為0 8 def convert(value): 9 matched = value.group() 10 res = None 11 if int(matched) >= 50:#注意matched是str格式,需要轉成int格式 12 res = '100'#數字不能作為返回值,需要將int轉成str 13 else: 14 res = '0' 15 return res 16 17 18 r = re.sub('\d{2}', convert, s) 19 print(r)
13、search與match
實際沒有findall好用
match:嘗試從字符串首字母開始匹配,如果找不到返回None,找到第一個即返回。
search:嘗試搜索整個字符串,找到第一個即返回
1 #coding=utf-8 2 import re 3 ''' 4 檢索所有數字 5 ''' 6 s='A83C72D8E67' 7 8 r=re.match('\d',s) 9 #從首字母開始匹配數字 10 print(r) 11 r1=re.search('\d',s) 12 #返回對象,包含位置信息等 13 print(r1) 14 #獲取查詢結果,匹配一次即返回 15 print(r1.group())