web开发利器--正则表达式(re模块 search findall sub split方法)

正则表达式篇

  1. 过滤必要信息
  2. 数据清洗

python中正则表达式的应用

python中通过re模块来进行使用正则表达式

主要实现流程为

import re
#使用match方法进行匹配操作
result =re.match(正则表达式,要匹配的字符串)
#如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()

match的语法 re.match(r"Hello","Hello word")

前面必须要加一个r

正则表达式简而言之分为以下几个部分

  1. 匹配单个字符
  2. 匹配多个字符
  3. 匹配开头结尾
  4. 匹配分组

首先先了解匹配单个字符的规则

匹配单个字符

字符功能
.匹配任意一个字符(除了\n)
[]匹配[]中列举的字符
\d匹配数字即 0-9
\D匹配非数字 即不是数字
\s匹配空白即空格或 tab键
\S匹配非空白字符
\w匹配单词字符,即a-z ,A-Z , 0-9, _
\W匹配非单词字符

匹配连续数据

import re
re.match(r"速度与激情[1-9]","速度与激情8").group()

我们也可以进行分块匹配非连续数据

import re
re.match(r"速度与激情[1-36-9]","速度与激情8").group()

我们如果要想匹配带字母的和数字混合的

import re
re.match(r"速度与激情[1-8abcd]","速度与激情a").group()

在连续/非连续数据上加入想要匹配的单个字符/连续字符

import re
re.match(r"速度与激情[1-8a-z]","速度与激情g").group()

这里需要注意的是,在正则匹配中,严格区分大小写

import re
re.match(r"速度与激情[1-8a-zA-Z]","速度与激情G").group()

这里单一匹配显得很low,我们可以通过匹配的法则来进行定向匹配

import re
re.match("速度与激情\w","速度与激情_").group()
>>速度与激情_

匹配规则匹配数字

import re
re.match("速度与激情\d","速度与激情4").group()
>>速度与激情4

\w可以匹配任意字符,包括下划线 _

\d匹配任意数字

\s 匹配空白字符或者tab键(用的比较少)

.点就比较牛的,可以匹配任意字符

匹配多个字符(配合其他规则执行进行匹配的)

字符功能
*匹配前一个字符出现出现0次或者无限次,即可有可无
+匹配前一个字符出现一次或者无限次,即至少1次
?匹配前一个字符出现1次或者0次,即要么一次要么没有
{m}匹配前一个字符串出现m次
{m,n}匹配前一个字符串出现从m到n次

示例:

需求:匹配出一个字符第一个字母为大小写字符,后面都是小写字母并且这些小写字母可有可无

import re
ret =re.match("[A-Z][a-z]*","N")
print(ret.group())
>>N

如果我要是想匹配一个/两个的话,不确定是几,那么我们就需要用到正则规则来进行编写

import re
re.match("速度与激情\d{1,2}","速度与激情14").group()

解释一下上述代码,对于\d来说,他是匹配数字的正则规则,对于后面的{}它的实际意义是作用于前面的 \d 意思是判断有一个数字或者两个数字都行 {1,2}代表的就是1/2数字要是 {1,3}的话就是三位数也行

应用场景:一般这种正则规则都应用在网站注册界面,比如我指定判断为11位的手机号

import re
re.match("\d{11}","12345678901").group()

如果中间有空格也不行大括号无论前面是什么,作用的都是前面的东西 比如 速度与激情a{1,3} 那么匹配速度与激情a/速度与激情aa/速度与激情aaa均可成功匹配

我对 {}中的 理解是,里面相当于或,什么都行的意思,这个可以,那个也可以,直至规则限定数字,而不加逗号 的意思就是必须是限定的这个位数,有一点不符合规则的都不行

下面说一下的匹配规则:

是作用于前面那个东西,可以有可无,有的话只能有一个,要么就不能有!!!!!!

比如在网页上匹配手机号

re.match(r"021-?\d{8}","024-12345678").group()
>>021-12345678

但是如果我要是不加 -,作用结果就是,同样不会报错,也可以成功的匹配。

#匹配沈阳的手机号
re.match(r"021-?\d{8}","02412345678").group()
>>02112345678

#匹配济南的手机号 #匹配前面是3位或者四位的手机号
re.match(r"\d{3,4}-?\d{8}","0532-12345678").group()
>>0532-12345678

.*可以匹配任意一个字符,但是不包括换行\n

如果要是有换行的话那么就需要引入一个新的参数,就可以全部的提取到了

html_spyder ="""adasda
sdasd
asd
as
d
asd"""
result =re.match(r".*",html_spyder,re.S).group()
>>	adasda
	sdasd
	asd
	as
	d
	asd

.+就和 .*想对应, .+当是空字符的时候就会报错(至少有一个),但是 .*永远不会报错(什么都行)

实例分析:

import re
names =["age","_age","1age","age1","a_age","age_1","age!","a#123"]
for name in names:
    result = re.match(r"[a-zA-Z0-9_][a-zA-Z0-9_]*",name)
    if result:
        print("匹配结果为%s匹配出来的结果为%s"%(result,result.group()))
    else:
        print("匹配失败!")

运行结果:

D:\BaiduNetdiskDownload\python-3.6.6\python.exe G:/python/正则表达式.py
匹配结果为<_sre.SRE_Match object; span=(0, 3), match='age'>匹配出来的结果为age
匹配结果为<_sre.SRE_Match object; span=(0, 4), match='_age'>匹配出来的结果为_age
匹配结果为<_sre.SRE_Match object; span=(0, 4), match='1age'>匹配出来的结果为1age
匹配结果为<_sre.SRE_Match object; span=(0, 4), match='age1'>匹配出来的结果为age1
匹配结果为<_sre.SRE_Match object; span=(0, 5), match='a_age'>匹配出来的结果为a_age
匹配结果为<_sre.SRE_Match object; span=(0, 5), match='age_1'>匹配出来的结果为age_1
匹配结果为<_sre.SRE_Match object; span=(0, 3), match='age'>匹配出来的结果为age
匹配结果为<_sre.SRE_Match object; span=(0, 1), match='a'>匹配出来的结果为a

匹配开头结尾,我们可以发现,age!后面的并没有匹配到,这里我们需要改造一下代码

字符功能
^匹配字符串开头
$匹配字符串结尾
import re
names =["age","_age","1age","age1","a_age","age_1","age!","a#123"]
for name in names:
    result = re.match(r"^[a-zA-Z0-9_][a-zA-Z0-9_]*[!#]?[0-9]*$",name)
    if result:
        print("匹配结果为%s匹配出来的结果为%s"%(result,result.group()))
    else:
        print("匹配失败!")

项目实战: 判断168邮箱是否正确匹配,@符号前面有4到20位,例如hello@168.com

import re
def main():
    email =input("请输入邮箱地址:")
    #如果在正则表达式中用到了某些普通字符,比如?等,仅仅在他们前面加一个\进行转义
    result =re.match("[a-zA-Z0-9]{4,20}@163\.com$",email)
    
    if email:
        print("您的邮箱为:%s"%(result))
    else:
        print("请重新输入!")
if __name__ == '__main__':
    main()

匹配分组

字符功能
|匹配左右任意一个表达式
(ab)将括号中字符作为一个分组
\num引用分组num匹配到的字符串
(?P<name>)分组起别名
(?P=name)引用name分组匹配到的字符串

管道 | 尽量不要加,他的意思是或的意思,在管道的前后分为两个部分,前面可以,后面也可以

但是如果我要是想判断多个邮箱的话那么只需要对其进行改造就可

re.match(r"[a-zA-Z0-9_]{4,20}@(163|126)\.COM$","laowang@126.com").group()

>> laowang@126.com
re.match(r"([a-zA-Z0-9_]{4,20})@(163|126)\.COM$","laowang@126.com").group(1)
>> laowang

对于分组,我们主要以网页端<h1>为例。

html_str ="<h1>rwerwerwer</h1>"
re.match(r"<\w*>.*</\w*>",html_str).group()

我们重新改造一下在第一个分组同样可以成功匹配

html_str ="<h1>rwerwerwer</h1>"
re.match(r"<(\w*)>.*</\1>",html_str).group()

改造(这里一定要注意顺序,千万不要按正常的思考方式来进行思考,倒着思考更好)

html_str ="<h1>rwerwerwer</h1>"
re.match(r"<(\w*)><(\w*)>.*</\2></\1>",html_str).group()

升级,如果我要是想通过分组的方式来进行处理字符串

html_str ="<h1>rwerwerwer</h1>"
re.match(r"<(?P<p1>\w*)><(?P<p2>\w*)>.*</(?P=p2)></(?P=p2)>",html_str).group()

re模块的高级用法(python特有方法):

search方法:(这个方法于match方法的区别是,它并不是从第一个字符匹配的)如果要是想达到match方法就在匹配方式前面加一个 ^

import re
response =re.search(r"\d+","阅读次数 9999").group()
 >>9999

但是它只能匹配到第一个满足要求的字符,后面不会去匹配了

findall方法: 匹配到规则内所有符合要求的字符

import re
response =re.findall(r"\d+","阅读次数 9999 C++=1123 java =123213").group()
 >>['9999','1123','123213']

sub方法,将匹配到的数据进行替换

import re
response =re.sub(r"\d+","678","阅读次数 9999").group()
 >>阅读次数 678

先那正则去匹配,然后将匹配到的数据进行和前面的替换

业务场景:如果想把匹配到最后的结果+1,那么就应该用下面的方式来进行审计

import re
def add(temp):
    strnum =temp.group()
    num =int(strnum)+1
    return str(num)

result =re.sub(r'\d+',add,"python =997")
print(result)

split方法,根据匹配进行切割字符串,并返回一个列表

需求,切割字符串 info:xiaozhang33shandong

import re
result =re.split(r":|"," info:xiaozhang 33 shandong")
print(result)
import re
text = "123123qweq@qq.com"
reslut=re.match(r"\w+@[0-9a-z]+\.com",text)
print(reslut.group())
import re
text ="https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9337143847801671495%22%7D&n_type=0&p_from=1"
result =re.match(r"(http|https|ftp)://[^\s]+",text).group()
print(result)

匹配身份证

result =re.match(r"\d{17}[\dXx]",text).group()
print(result)

(ftp|http|https)$ 使用 |时候必须要用括号括起来

贪婪模式和非贪婪模式:

\d+贪婪模式,默认的回去匹配更多的字符串

\d+?非贪婪模式,只会去匹配一个

text ="<h1>标题</h1>"
ret =re.match("<.+?>",text)
print(ret.group())

>>标题

如果要是不加问号的话则会全部匹配到 <h1>

案例:匹配0-100之间的数字 09不可以出现 101不可以出现 有三种情况 一位数 两位数 三位数

text ="99"
ret =re.match("[1-9]\d?|100",text)
print(ret.group())
import re
text = "100"
result = re.match("[0-9]\d?$|100$",text).group()
print(result)
import re
text ="apple is price $99 orange is $032"
result =re.match("(.*)(\$\d+)(.*)(\$\d+)",text)
print(result.group(2,4))

拉取拉勾网的信息

import re
text ="""<div class="job-detail">
        工作职责:
<br>1、协同完成网站的开发与测试工作;
<br>2、独立完成网站的功能模块编码;
<br>3、参于各项目中的编码工作。
<br>
<br>任职要求:
<br>1、掌握PHP语言,有项目开发经验优先;
<br>2、掌握SQL语句和MySQL数据库;
<br>3、掌握PHP面向对象思想和具有MVC设计思想,良好的代码书写、注释习惯;
<br>4、了解HTML,HTTP等技术;
<br>5、善于学习,有较强的学习能力,工作主动,责任心强,能承受一定工作压力。
        </div>"""
result =re.sub('<.+?>',"",text)
print(result)
text = "hello&& word ni hao"
result =re.split('^a-zA-Z',text)
print(result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学成七步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值