- 一、初识正则表达式
- 1.1 是什么?
- 1.2 用来干什么?
- 1.3 具体应用
- 1.4 基本组成元素
- 二、正则表达式的匹配规则
- 2.1 匹配字符
- 2.1.1 单个字符
- 2.1.2 多个字符
- 2.1.3 常用的特殊表达式
- 2.2 匹配循环和重复
- 2.2.1 常用的特殊表达式
- 2.3 位置和边界
- 2.3.1 单词边界
- 2.3.2 字符串边界
- 2.3.3 常用的特殊表达式
- 2.4 分支条件
- 2.5 分组
- 2.6 懒惰和贪婪匹配
- 三、Python中的re模块
- 1.re.match( )
- 2.re.serach( )
- ......
一、初识正则表达式 1.1 是什么?
用来描述特定规则的表达式。
1.2 用来干什么? 可以用来检查一个字符串中是否含有满足特定规则的子串,可以将满足的子串替换或者取出等。
1.3 具体应用-
验证身份z、邮箱、手机号格式是否正确
-
网站验证
-
爬虫
…
案例演示:
邮箱格式错误
邮箱格式正确
1.4 基本组成元素正则表达式的基本组成元素可以分为:字符和元字符。字符就是普通的字符,通常正则表达式里面使用的就是数字、英文字母。而元字符,也叫特殊字符,是一些用来表示特殊语义的字符。如^表示非,|表示或等。利用这些元字符,才能构造出强大的表达式模式(pattern)。
二、正则表达式的匹配规则 2.1 匹配字符最简单的正则表达式可以由简单的数字和字母组成,没有特殊的语义,纯粹就是一一对应的关系。如想在’dog’这个单词里找到’d’这个字符,就直接用/d/这个正则就可以了。
2.1.1 单个字符- 如果想要匹配特殊字符的话,就得使用一个元字符 ,它是转义字符,顾名思义,就是让其后面跟着的那个字符失去其本来的含义。
例如:要匹配这个符号,由于这个符号本身是个特殊字符,指出现零次或多次,所以如果要单纯的匹配*这个符号,就要利用转义元字符来让它失去其本来的含义:/*/(就像我们编程语言里的关键字,已经有特定的含义) - 如果本来这个字符不是特殊字符,使用转义符号就会让它拥有特殊的含义。我们常常需要匹配一些特殊字符,比如空格,制表符,回车,换行等, 而这些就需要我们使用转义字符来匹配。
常用的特殊表达式:
-
单个字符的对应关系是一对一的,我们可以通过集合区间和通配符的方式就可以实现一对多的匹配。
-
在正则表达式里,集合的定义方式是使用中括号[]。如/[123]/这个正则就能同时匹配1,2,3三个字符。那如果我们想匹配所有的数字怎么办呢?从0写到9显然太过低效,所以元字符-就可以用来表示区间范围,利用/[0-9]/就能匹配所有的数字, /[a-z]/则可以匹配所有的英文小写字母。那如果我想匹配所有的数字和所有的字母怎么办呢?/[0-9a-zA-Z]/
-
如果要同时匹配多个字符也还是要一一列举,这是不方便的。所以在正则表达式里有一批用来同时匹配多个字符的简便正则表达式:
使用限定符:限定字符出现的次数
- 如何同时匹配多个字符:要实现多个字符的匹配我们只要多次循环,重复使用我们的之前的正则规则就可以了。那么根据循环次数的多与少,我们可以分为0次,1次,多次,特定次。
- 0|1次:元字符?代表了匹配一个字符或0个字符。如果你要匹配color和colour这两个单词,就需要同时保证u这个字符是否出现都能被匹配到。所以你的正则表达式应该是这样的:/colou?r/
- 大于等于0次:元字符*用来表示匹配0个字符或无数个字符。通常用来过滤某些可有可无的字符串。
- 大于等于1次:元字符+适用于要匹配同个字符出现1次或多次的情况。
- 特定次数:在某些情况下,我们需要匹配特定的重复次数,元字符{}用来给重复匹配设置区间范围。如’a’需要匹配3次,那么我就使用/a{3}/这个正则,或者说’a’我想匹配至少两次就是用/a{2,}/这个正则。
案例1:检验密码长度是否为6-12位
# 案例1.密码合法校验 import re str = input("请输入6-12位密码: ") # 判断输入的字符串是否满足从起始位置连续6-12个数字这一规则,若满足返回正则匹配对象,否则返回None res = re.match('d{6,12}', str) print(res) if res is None: print("你输入的是个锤子!") else: print("密码输入合法!")2.3 位置和边界
除了字符匹配,我们还需要位置边界的匹配。在长文本字符串查找过程中,我们常常需要限制查询的位置。比如我只想在单词的开头结尾查找。
2.3.1 单词边界单词是构成句子和文章的基本单位,一个常见的使用场景是把文章或句子中的特定单词找出来。如:
The cat scattered his food all over the room.
我们想找到cat这个单词,但是如果只是使用/cat/这个正则,就会同时匹配到cat和scattered这两处文本。这时候我们就需要使用边界正则表达式b,其中b是boundary(边界)的首字母。在正则里它其实匹配的是能构成单词的字符(w)和不能构成单词的字符(W)中间的那个位置。
上面的例子改写成/bcatb/这样就能匹配到cat这个单词了。
2.3.2 字符串边界匹配完单词,我们再来看一下一整个字符串的边界怎么匹配。元字符^用来匹配字符串的开头。而元字符$用来匹配字符串的末尾。
在用户注册界面对页面上的数据进行校验时,经常要把元字符^和$结合起来使用,这样做的目的是防止部分匹配。比如说用/w{6,12}验证一个长度 6-12位的密码:虽然按照/w{6,12}的匹配原则确实跟我们预想的一样,
但用户录入的 13 位长数据也是合法的。其中的原因就是/w{6, 12} 只是说匹配在 12 位之内,而正则表达式只寻找能匹配上的内容,对于匹配不上的内容会被它忽略掉,并不会告诉我们它是部分匹配还是全部匹配。
# 案例1升级版.密码合法校验 import re str = input("请输入6-12位密码: ") # 判断输入的字符串是否满足从起始位置连续6-12个数字这一规则,若满足返回正则匹配对象,否则返回None res = re.search('^d{6,12}$', str) print(res) if res is None: print("你输入的是个锤子!") else: print("密码输入合法!")2.3.3 常用的特殊表达式
分支条件指的是有几种规则,如果满足其中任意一种规则都能匹配成功,与Python中的or类似,具体方法是用|把不同的规则分隔开。最简单的例子,如: X|Y, 指的是X和Y都可以匹配成功。
2.5 分组我们已经学习了怎么重复单个字符(直接在字符后面加上限定符就行了,如:'a’重复4次,a{4} );但如果想要重复多个字符又该怎么办?我们可以用小括号分组(子表达式),然后我们就可以指定这个子表达式的重复次数了。
(d{1,3}.){3}d{1,3}是一个简单的IP地址匹配表达式。
按顺序分析它:
d{1,3}匹配1到3位的数字,
(d{1,3}.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,
最后再加上一个一到三位的数字(d{1,3})。
但是,它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择字符来描述一个正确的IP地址:((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)
# 案例2.ip地址合法校验 import re str = input("请输入ip地址: ") # 判断输入的ip地址是否合法,ip地址由4组数字组成,每组数字之间以.分隔,每组数字的取值范围是0~255. # 只考虑数字,没有考虑数字的大小范围 #res = re.match('^(d{1,3}.){3}d{1,3}$', str) res = re.match('^((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)$', str) print(res) if res is None: print("你输入的是个锤子!") else: print("密码输入合法!")2.6 懒惰和贪婪匹配
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
re.match() 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None。
函数语法:re.match(pattern, string, flags=0)
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
re.search() 扫描整个字符串并返回第一个成功的匹配。
匹配成功re.search()方法返回一个匹配的对象,否则返回None。
函数语法:re.search(pattern, string, flags=0)
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)