目录
一、正则表达式介绍
正则表达式,顾名思义,是符合一定规则的表达式,是用于匹配字符串中字符组合的模式。常用作文本编辑器中检索,替换的功能或对输入的字符串进行合法性验证。
例如:在输入邮箱用户名时,系统会对输入进行合法性验证,如果不符合邮箱用户名(6-18个字符,可使用字母,数字,下划线,需以字母开头,后加@以及邮箱地址等)的格式,就会报错,这里所使用的验证方式一般就是正则表达式。
正则表达式的设计思想就是使用一些描述性的符号和文字为字符串定义一个规则,凡是匹配这个规则的,程序就认为该文本是匹配的,否则就是不匹配的。
二、正则表达式语法
1.普通字符
(1)判断长度为1的字符串是否为数字:
[0123456789]
方括号[ ]表示这是一个字符组,一对方括号中的值(0123456789)代表一个字符的正则表达式,只要输入字符和方括号中任意一个字符相同,即为匹配成功。
但是把每个字符都列出来过于繁琐,所以Python规定如果字符是连续有序的,可以用“-”省略。
[0-9]
(2)判断长度为1的字符串是否是小写字母:
[a-z]
注意:不能用[A-z]来表示所有英文字母(包括大写和小写),因为大写字母和小写字母的ASCII码并不连续,正确的表达方式为:
[A-Za-z] #或 [a-zA-Z]
(3)判断长度大于1的字符串:
#判断字符串是否为一个二位数
[0-9][0-9]
#判断字符串是否为一个三位数
[0-9][0-9][0-9]
显然,需要判断的字符串有几位数,就用几对方括号,每对方括号表示一个字符。
(4)如果要判断输入是不是Y(或y),可以用:
[Yy]
如果要判断Yes或yes,可以将相同的部分只写一遍:
[Yy]es
2.字符转义
在上面我们学习了表示数字的正则表达式"[0-9]",我们知道其中“-”代表的是范围,而不是符号本身,如果需要判断字符是不是在“0”,“-”,“9”这三个字符中的一个,就需要使用转义字符了。
在Python中,字符转义都有通用的方法,就是在符号前加上“ \ ”,用转义字符解决上述问题,即:
[0\-9]
需要注意的是,Python中还有很多类似“-”这样不止一个意思的符号,我们称这类有特殊意思的符号为元字符。
常见元字符例子(图片来源网络,侵删)
3.限定符
限定符指输入中必须存在字符,组或字符类的多个实例才能找到匹配项,简单来说,就是字符串较长且字符类型单一时,可以用限定符简单化正则表达式。
下面介绍一些例子:
“{n}”限定符表示匹配前面一个元素n次,n可以为任何整数。例如“y{5}”可匹配“yyyyy”;3{2}可匹配“33” ; “\w{3}”表示可以匹配任意的三位英文字母,如“yes”,“Not”。
“{n,}”限定符表示至少匹配上一元素n次,例如“y{n,}”可以匹配“yyy”,也可以匹配“yyyy”。
“{n,m}”限定符表示至少匹配上一元素n次,但不能超过m次,例如“y{3,5}”可以匹配“yyy”,“yyyy”,“yyyyy”。
此外,还有一些常用的限定符,在此简要说明:
“ * ”限定符表示与前一元素匹配0次或多次,相当于“{0,}”。
“ + ”限定符表示与前一元素匹配1次或多次,相当于“{1,}”。
“ ?”限定符表示与前一元素匹配0次或1次,相当于“{0,1}”
4.定位符
定位符用于限制所给模式字符串在完整字符串中的位置。
“ ^ ”指定模式匹配必须从字符串第一个字符开始,例如“\[a-z]+”可以匹配“123abc”中的“abc”,但“^\[a-z]+”不可以匹配“123abc”中的“abc”,因为“abc”并不在字符串的开头。
“ $ ”指定前面的模式必须出现在字符串的结尾,,例如“\[a-z]+”可以匹配“abc123”中的“abc”,但“$\[a-z]+”不可以匹配“abc123”中的“abc”,它可以匹配“123abc”中的abc。
“ \b ”指定匹配必须在单词字符和非单词字符的边界上,(单词字符包括字母,数字和下划线),常常用于匹配单词是否在整个句子中,例如“\bare\b”用于匹配所有的“are”,并且排除句子中包含“are”的单词的影响(因为are的前后都必须为空格)。
“ \B ”指定匹配不能出现在单词边界上,与“ \b ”相反,例如“\Bqu\w+”意味着找到不以qu开头的单词,例如equity中的“quity”;对于“queen”,则无法匹配。
5.分组构造
分组构造描述了正则表达式的子表达式,用于捕获输入字符串的子字符串。简要来说,“()”里面的内容即为捕获的子组,例如:
对“I will be a good student.”使用 “(\w+)\s(\w+)\W”进行模式匹配。“\s”匹配空白字符,“\W”匹配非单词字符,\w+匹配长度超过1的字符串(即为单词),结果为:
“I will” 一组,其中“I”和“will”为两个子组;“be a”一组,其中“be”和“a”为两个子组;“good student.”一组,其中“good”和“student.”为两个子组。
三、re模块
这里只简要概括相关内容
关于re模块的具体分析可参考文章:http://t.csdn.cn/QzDFf
1.re模块介绍
re模块是Python标准库中提供的正则表达式匹配操作模块。
正则表达式中很多的元字符都用反斜线“\”开头,这与Python字符串中相同的字符使用产生冲突,极端情况下,想要匹配“ \ ”,需要将正则表达式写成“ \\\\”,因为正则表达式中要用“ \\ ”表示“ \ ”,Python中的字符串也要用“ \\ ”表示“ \ ”。
为了解决这种麻烦,我们可以用前缀“ r ”,该前缀表示不以任何形式处理反斜线” \ “。例如:
print('\\\\') #输出\\
print('\\') #输出\
print(r'\\') #输出\\
print('\n') #输出一个换行符
print(r'\n') #输出“\n”字符
2.compile函数
complie函数用于编译正则表达式,生成一个对象。
import re
pattern = re.compile(r'\w+')
下面就可以用pattern这个对象来进行模式匹配了。
3.match函数
match函数用于查找字符串指定位置正则匹配,如果未指定位置,从第一个位置开始模式匹配,得到一个结果就会返回。(若匹配,则返回值,若不匹配,则返回None)
import re
pattern = re.compile(r'\d+') #匹配至少一个数字
m1 = pattern.match('one123') #未指定位置,默认从第一个字符开始
print(m1) #与第一个字符模式比较,不匹配,输出None
m2 = pattern.match('one123',3,5)
print(m2) #输出位置3到位置5的两个数,即12
print(m2.group()) #输出12
m3 = re.match(r'\d+','one123')#直接对整个字符串正则匹配
print(m3) #输出None
m4 = re.match(r'[a-z]+','Abcde',re.I)#忽略大小写模式re.I
print(m4)
print(m4.group())
编译结果如下:
其中group()方法用于提取数据。
4.re.search方法
search方法用于查找字符串指定位置正则匹配,同样也只匹配一次,返回一个结果。
match方法与search方法的区别:match需要完全满足正则表达式才能返回,search函数只需要字符串包含匹配正则表达式的子串就认为匹配。
import re
pattern = re.compile(r'\d+') #匹配至少一个数字
m1 = pattern.search('one123') #未指定位置,默认匹配整个字符串
print(m1) #与match有区别,one123中包含数字即可
print(m1.group()) #提取数字,输出123
m2 = pattern.search('one123',0,4)
print(m2) #位置0到位置4之间有one1,包含1
print(m2.group()) #输出1
m3 = re.search(r'\d+','one123')#不使用模式对象的匹配
print(m3)
print(m3.group())
m4 = re.search(r'[a-z]+','Abcde',re.I)#忽略大小写模式re.I
print(m4)
print(m4.group())
编译结果如下:
5.re.findall方法
match函数和search函数都是匹配到一个结果就返回,findall可以获取全部匹配结果。
此外,findall函数不会返回None,不管有没有结果,都会返回一个列表。
import re
pattern = re.compile(r'\d{2}') #匹配两个数字
m1 = pattern.findall('one1234')#未指定位置,默认匹配整个字符串
print(m1) #one1234中包含两组2位数字12 34
m2 = pattern.findall('one123',0,4)
print(m2) #位置0到位置4之间有one1,但是没有2位数字
m3 = re.findall(r'\d+','one123')#不使用模式对象的匹配,1位以上的数字
print(m3)
m4 = re.findall(r'[a-z]','Abcde',re.I)#忽略大小写模式re.I,每次只匹配一个字母
print(m4)
编译结果如下:
6.re.split方法
split方法下的字符串只能完全匹配相同的字符,遇到匹配项时分割字符串。
import re
pattern = re.compile(r'[\s\,\;]+') #匹配空格,”,“和”;“
m1 = pattern.split('a,b;; c d') #遇到匹配的字符,就分割字符串一次(不输出匹配项)
print(m1)
m2 = re.split(r'[\s\,\;]+','a,b;; c d')
print(m2)
编译结果如下:
7.re.sub方法
sub方法是使用正则表达式替换字符串的一种方法。
import re
s = 'hello 123 world 456'
pattern = re.compile(r'(\w+) (\w+)') #注意中间的空格
m1 = pattern.sub('hello world',s) #用hello word替换hello 123和world 456
print(m1) #hello world hello world
m2 = pattern.sub('hello world',s,1) #只替换一次
print(m2) #hello world world 456
m3 = re.sub(r'(\w+) (\w+)','hello world',s,1) #只替换一次
print(m3) #hello world world 456
编译结果如下:
四、简单例题
1.判断输入邮箱地址是否为有效地址
具体解析可参照:http://t.csdn.cn/rGAtQ
import re
pattern = re.compile(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$')
def is_email(email):
if pattern.match(email):
print("这是一个有效的邮箱地址",email)
else:
print("这是一个无效的邮箱地址",email)
email = input("请输入一个邮箱地址:")
is_email(email)