正则表达式常用操作

正则表达式的概念与作用

概念:正则表达式是一种字符串匹配的模式
作用:检查一个字符串是否含有某个子串;替换匹配的子串;提取某个字符串中的子串(爬虫中常用)

示例

#先导入模块
import re

普通字符匹配

#后面这个字符串中是否有前面这个字符串 有就返回前面这个字符串 没有就返回空列表
print(re.findall('abc','abc'))#有就返回
print(re.findall('abc','adc'))#adc中没有abc所以就返回空
print(re.findall('abc','dabcf'))#只要里面有abc就行
print(re.findall('dabcf','abc'))#反过来当然不行了

[‘abc’]
[]
[‘abc’]
[]

点号

#可以匹配除了换行符以外的任意一个字符
print(re.findall('a.c','abc'))
print(re.findall('a.c','a&c'))
print(re.findall('a...c','abddc'))
print(re.findall('a.c','a\nc'))#换行符就不行了

[‘abc’]
[‘a&c’]
[‘abddc’]
[]

print(re.findall('a.c','a.c'))
print(re.findall('a\.c','a.c'))#要是我只想匹配 点符号   可以试一下转义符
print(re.findall('a\.c','abc'))#此时abc就不行了,转义符号的作用就发挥出来了

[‘a.c’]
[‘a.c’]
[]

中括号

#中括号里面是否包含 后面
print(re.findall('a[bc]d','abd'))
print(re.findall('a[bc]d','acd'))
print(re.findall('a[bc]d','aed'))

[‘abd’]
[‘acd’]
[]

预定义的字符集

在这里插入图片描述

print(re.findall('\d','123'))#可以看到\d是可以匹配的,但是都分开了,因为d一次匹配一个字符)
print(re.findall('\w','Az123'))#\w可以匹配字符和数字
print(re.findall('\w','Az123中文'))#中文也是可以的
print(re.findall('\w','Az123中文$%^'))#特殊字符就不行了

[‘1’, ‘2’, ‘3’]
[‘A’, ‘z’, ‘1’, ‘2’, ‘3’]
[‘A’, ‘z’, ‘1’, ‘2’, ‘3’, ‘中’, ‘文’]
[‘A’, ‘z’, ‘1’, ‘2’, ‘3’, ‘中’, ‘文’]

数量词

print(re.findall('abc*','abcc'))#两次c是可以的
print(re.findall('abc*','abccc'))#3次c是可以的
print(re.findall('abc*','ab'))#0次也是可以的
print(re.findall('abc*','abc'))#一次也是可以的

[‘abcc’]
[‘abccc’]
[‘ab’]
[‘abc’]

print(re.findall('a\d*','a123'))# \d可以匹配数字
print(re.findall('a\d*','a1234'))
print("看图查表就行了 不意义列举")

[‘a123’]
[‘a1234’]

findall()方法

import re
## findall方法,返回匹配的结果列表#
print(re.findall('\d','chaun12zhi24'))#因为\d匹配数字,匹配一个字符,所以就返回了下面几个数字
print(re.findall('\d+','chaun12zhi24'))#符号“+”的作用就显示出来了 匹配前一个字符一次或者无限次 这里是数字

[‘1’, ‘2’, ‘2’, ‘4’]
[‘12’, ‘24’]

## findall方法中flag参数的作用
print(re.findall('a.bc','a\nbc'))#此时匹配不了,前面 .和\n 不能匹配
print(re.findall('a.bc','a\nbc',re.DOTALL))#这样 点符号就可以匹配任何字符了 包括换行符
print(re.findall('a.bc','a\nbc',re.S))#这样 点符号就可以匹配任何字符了 包括换行符

[]
[‘a\nbc’]
[‘a\nbc’]

## findall方法中flag分组的使用
print(re.findall('a.+bc','a\nbc',re.DOTALL))#如果没有()则返回与整个正则匹配的列表
print(re.findall('a(.+)bc','a\nbc',re.DOTALL))#如果有()则只返回()里面的内容,小括号两边的东西负责确定提取数据所在位置

[‘a\nbc’]
[‘\n’]

r原串

#1在不使用r原串的时候,遇到转移字符怎么做
print(re.findall('a\nbc','a\nbc'))#这个时候可以匹配成功
print(re.findall('a\\nbc','a\\nbc'))#这两种情况都匹配不上
print(re.findall('a\nbc','a\\nbc'))#这两种情况都匹配不上
print(re.findall('a\\\nbc','a\\nbc'))#三个斜杠匹配不上
print(re.findall('a\\\\nbc','a\\nbc'))#4个斜杠匹配上了 官方文档就这么规定的

[‘a\nbc’]
[]
[]
[]
[‘a\nbc’]

print(re.findall(r'a\nbc','a\nbc'))#r原串在正则中就可以消除转义符带来的影响
print(re.findall(r'\d','a123'))#扩展:可以解决写正则的时候,不符合PEP8规范的问题

[‘a\nbc’]
[‘1’, ‘2’, ‘3’]

举例应用

1.验证手机号

手机号码的规则是1开头,第二位是34587,后面那9位就可以随意了

text="13267228730"#这是一个电话号码 当然是字符串类型的 
ret=re.findall('1[34578]\d{9}',text)#第一位是1;第二位是[],就是34578中的一个;\d代表数字0-99}代表匹配前一个字符m次  \d{9}在一起就是代表9位都是数字 
print("这样就可以把前11位匹配的结果拿到了: ",ret)#这样就可以把前11位匹配的结果拿到了  

#但是要判断是否是电话号码还不行  因为如果长度大于11以后也会匹配出来 比如上述电话号码后面再加一个数字照样可以得到前11位

text="132672287300"#这个在原来电话号码后面又多加了一个0
ret=re.findall('1[34578]\d{9}',text)
print("电话号码之后再加一个0照样可以匹配出来前11位: ",ret)

#所以严谨期间 可以先判断一下号码是不是11位
def is_telnum(tel):
    tel=str(tel)#有时候输入的可能是数字电话号码(整形) 想更严谨一点可以在这里加一个判断 如果里面有 (数字或者数字组成的字符串)之外的东西 比如标点符号或者汉字 就直接返回 输入有误
    return len(str(tel))==11 and re.findall('1[34578]\d{9}',tel)!=[]#这里先判断一下 输入的电话号码是不是11位  然后用正则表达式判断一下 就OK了

print("13267228730是否是电话号码: ",is_telnum("13267228730"))#这个是电话号码
print("1326722873是否是电话号码: ",is_telnum("1326722873"))#这个不是
print("132672287300是否是电话号码: ",is_telnum("132672287300"))#这个多了一位 也不是
print("12267228730是否是电话号码: ",is_telnum("12267228730"))#12开头的也不是电话号码

运行结果如下:
这样就可以把前11位匹配的结果拿到了: [‘13267228730’]
电话号码之后再加一个0照样可以匹配出来前11位: [‘13267228730’]
13267228730是否是电话号码: True
1326722873是否是电话号码: False
132672287300是否是电话号码: False
12267228730是否是电话号码: False

2.验证是否是邮箱

邮箱的前面可以是数字或者字符或者下划线,然后是@ 然后是哪家邮箱 比如qq 126 163 那就是数字或英文字母 然后是 . 然后是com cn net之类 就是纯英文

#这里用了match方法 和find_all的方法区别是从头开始匹配 然后返回值要加上.group()
text="809088864@qq.com"
ret=re.match('\w+@[a-z0-9]+\.[a-z]+',text)
print(ret.group(),' ',type(ret.group()))
#\w匹配单词字符a-zA-Z0-9_,+代表前面这个单词字符至少要有一个 然后是@,[a-z0-9]就是@后面这个可以是小写英文(邮箱结尾没有大写)或者数字 +代表至少一个
#然后是.但是.是特殊字符 \.转义一下 然后是[a-z]小写字母 +就是至少要有一个
#上面出现了三个 + 号 不写就会报错 因为可能匹配到一个字符就停止了 加一个+号 保证匹配完
#(我不会偷偷告诉你 上面是我的qq邮箱 还可以加到我qq或薇信的)

809088864@qq.com <class ‘str’>
在这里插入图片描述

def is_mail(mail_num):
    ret=re.match('\w+@[a-z0-9]+\.[a-z]+[a-z]+',mail_num)
    return ret!=None and len(mail_num)==len(ret.group()) 
    #如果不判断一下len(mail_num)==len(ret.group()) songhehe0516@126.com6会匹配成songhehe0516@126.com 也会通过的 songhehe0516@126.co-m匹配成songhehe0516@126.co也会通过的
print(is_mail("songhehe0516@126.com"))
print(is_mail("songhehe0516126.com"))#少了一个@
print(is_mail("s*onghehe0516@126.com"))#插入了一个*print(is_mail("songhehe0516@126com"))#没有.
print(is_mail("songhehe0516@126.com6"))#尾部(菊部)加入了一个数字
print(is_mail("songhehe0516@126.co-m"))#后面加了一个-
True False False False False False

3验证是否是url

(当然这里没有考虑所有的情况 只是简单判断一下)
text="https://www.baidu.com/"
ret=re.match('(http|https|ftp)://[^s]+',text)
#开头是http https ftp 然后是: 然后// 然后是非空字符
print(ret.group())

https://www.baidu.com/

text="fss://www.baidu.com/"
ret=re.match('(http|https|ftp)://[^s]+',text)#不是url 就报错了
print(ret.group())

---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_4481/2786963643.py in
2 ret=re.match(‘(http|https|ftp)😕/[^s]+’,text)
3 #开头是http https ftp 然后是: 然后// 然后是非空字符 ^表示非 s代表非空字符
----> 4 print(ret.group())

AttributeError: ‘NoneType’ object has no attribute ‘group’

4验证身份证

#17个数字 最后一位是数字(\d) 或者xX(当然这里没有考虑所有的情况 只是简单判断一下)
text="42062119870516221X"
ret=re.match('\d{17}[\dxX]',text)
#             17个数字 最后一位是数字(\d) 或者xX

print(ret!=None)

text="42062119870516221"#少了一位数
ret=re.match('\d{17}[\dxX]',text)
print(ret!=None)

True
False

总结

不一定全部都记住,会用会查就OK(如果您发现我哪里写的不对,欢迎在评论区批评指正)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值