【2022-07-19】Python正则表达式
Python正则表达式
正则表达式的概念
- 什么是正则表达式?
- 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好对的一些特定字符、以及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑,主要用于数据的查找与筛选
正则表达式简介
- 正则表达式是对字符串(包括普通字符(例如,a到z之间的字母)和特殊字符(称之为“元字符”))操作的一种逻辑公式,就是用事先定义好对的一些特定字符、以及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串 。
在线测试工具
https://tool.chinaz.com/regex/
正则表达式之字符组
- 在同一个位置出现的多种字符组成一个字符组,在正则表达式中用中括号[]表示
- 单个字符组默认一次匹配一个字符
| 正则 | 待匹配字符 | 匹配结果 | 说明 |
|---|---|---|---|
| [0123456789] | 7 | True | 在一个字符组里枚举合法的所有字符,字符组里的任意一个字符 和"待匹配字符"相同都视为可以匹配 |
| [0123456789] | a | False | 由于字符组中没有"a"字符,所以不能匹配 |
| [0-9] | 6 | True | 也可以用-表示范围,[0-9]就和[0123456789]是一个意思 |
| [A-Z] | B | True | [A-Z]就表示所有的大写字母 |
| [a-z] | c | True | 同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 |
| [0-9A-Ya-h] | e | True | 可以匹配数字,大小写形式的a~f,用来验证十六进制字符 |
正则表达式之特殊符号
| 元字符 | 匹配内容 |
|---|---|
| . | 匹配除换行符以外的任意字符 |
| \w | 匹配数字或字母或下划线 |
| \W | 匹配非字母或数字或下划线 |
| \d | 匹配数字 |
| ^ | 匹配字符串的开头 |
| $ | 匹配字符串的结尾 |
| a|b | 匹配字符a或字符b |
| () | 匹配括号内的表达式,也表示一个组 |
| [....] | 匹配字符组中的字符 |
| [^.....] | 匹配除了字符组中字符的所有字符 |
正则表达式之量词
| 量词 | 用法说明 |
|---|---|
| * | 重复零次或者更多次 |
| + | 重复一次或者更多次 |
| ? | 重复零次或一次 |
| 重复n次 | |
| 重复n次或更多次 | |
| 重复n到m次 |
正则表达式之贪婪与非贪婪
贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
所有的量词默认都是贪婪匹配 但是如果在量词的后面紧跟一个问号
那么就会变成非贪婪匹配
小技巧:以后我们在使用贪婪匹配或者非贪婪匹配的时候一般都是用.或者.?
并且结束的标志有上述符号左右两边添加的表达式决定
| 正则 | 待匹配字符 | 匹配结果 | 说明 |
|---|---|---|---|
| <.*> | <script...script> | script>...script> | 默认为贪婪匹配,会匹配尽量长的字符串 |
| <.*?> | r'\d' | script> script> | 加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串 |
几个常用的非贪婪匹配Pattern
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
.*?的用法
. 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x
就是取前面任意长度的字符,直到一个x出现
正则表达式之取消转义
在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是"换行符"就需要对""进行转义,变成'\'。
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\n",字符串中要写成'\n',那么正则里就要写成"\\n",这样就太麻烦了。这个时候我们就用到了r'\n'这个概念,此时的正则是r'\n'就可以了。
| 正则 | 待匹配内容 | 匹配结果 | 说明 |
|---|---|---|---|
| \n | \n | False | 在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配 |
| \\n | \n | True | 转义\之后变成\\,即可匹配 |
| "\\\\n" | '\\n' | True | 如果在python中,字符串中的''也需要转义,所以每一个字符串''又需要转义一次 |
| r'\\n' | r'\n' | True | 在字符串之前加r,让整个字符串不转义 |
正则表达式中取消斜杠与字母的特殊含义 就是在斜杠前面加斜杠
\\n \n
\\\\n \\n
在python中有更加简便的写法
r'\n'
r'\\n'
正则表达式之实战演练
编写校验用户手机号的正则
0?(13|14|15|17|18|19)[0-9]{9}
编写校验用户身份证的正则
\d{17}[\d|x]|\d{15}
编写校验用户邮箱的正则
\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}
编写校验用户qq号的正则
[1-9]([0-9]{5,11})
编写校验用户手机号的正则
# import re
# 11位电话号码
# content = '00112233445566778899'
# numbers = re.search(r'[1-9][0-9]{10}', content, re.S).group()
# print(numbers)
import re
s1 = "15838477645dfdfdf15887988765dfdf1157990087651fd157385367891fdf15826789876qqq15838545678a"
# 方法一:限制手机号开头,或者手机号前面为非数字,且手机号结尾或者以非数字结尾
pattern1 = '(?:^|[^\d])(1\d{10})(?:$|[^\d])'
phone_list1 = re.compile(pattern1).findall(s1)
print(phone_list1)
# 结果为:['15838477645', '15887988765', '15826789876', '15838545678']
# 方法二:利用负向零宽断言,断言手机号前后不能出现数字
pattern2 = '(?<!\d)(1\d{10})(?!\d)'
phone_list2 = re.compile(pattern2).findall(s1)
print(phone_list2)
# 结果为:['15838477645', '15887988765', '15826789876', '15838545678']
编写校验用户身份证的正则
tuple_ID = ('622323199811300296',
'622323199801090258',
'62232320181603028x',
'6223232009061130256')
import re
for ID in tuple_ID:
# print(ID,len(ID),type(ID))
ret = re.match(
r'^\d{6}((19\d{2})|((200\d)|(201[0,8])))((0[13578]((0[1-9])|([1-2]\d)|30|31))|(0[2]((0[1-9])|([1-2]\d)))|(0[2469]((0[1-9])|([1-2]\d)|30))|(11((0[1-9])|([1-2]\d)|30))|(12((0[1-9])|([1-2]\d)|30|31)))\d{3}([0-9]|x)$',
ID)
if ret:
print(ret, end='**')
print(ret.group(),'该身份证号有效')
else:
print(ret, end='**')
print(ID, '该身份证号不合法')
# <re.Match object; span=(0, 18), match='622323199811300296'>**622323199811300296 该身份证号有效
# <re.Match object; span=(0, 18), match='622323199801090258'>**622323199801090258 该身份证号有效
# None**62232320181603028x 该身份证号不合法
# None**6223232009061130256 该身份证号不合法

浙公网安备 33010602011771号