加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式基本概念

发布时间:2020-12-14 06:07:26 所属栏目:百科 来源:网络整理
导读:一、 正则表达式概述 ? ? 1. 作用: ? ? ?1. 数据抓取,数据的清理 : 在网上抓取图片,清除网站中不雅的评论 2. 数据验证,比如验证邮箱的合法性,手机号码的合法性 ,11位数字 ? ? 2. 特点:通用性,跨语言 ? ? 主流语言都有正则表达式,而且表达式的规则

一、 正则表达式概述
? ? 1. 作用:
? ? ?1. 数据抓取,数据的清理 : 在网上抓取图片,清除网站中不雅的评论
2. 数据验证,比如验证邮箱的合法性,手机号码的合法性 ,11位数字


? ? 2. 特点:通用性,跨语言
? ? 主流语言都有正则表达式,而且表达式的规则都几乎相同的

二、 re模块
? ?提示: 命令行: ctrl+e :到命令行的尾部
? ? ? ? ? ? ? ? ? ? ctrl+A: 到命令行的头部
1. re模块的使用过程
? ? a>import re
? ret=re.match("itcast","itcast.cn")
? ret
b> 匹配成功没
在命令行输入:ret
? ?为空: 匹配失败
? ?不为空: 匹配成功
?
c> 查看结果
? ? ? ?ret.group()

2. 小结?
? ?1. re.match("正则表达式","要匹配的内容")
? ?2. re.match ()是匹配以xxx开头的字符串


三、 匹配单个字符

? ? ? ??

字符 功能
. 匹配任意1个字符(除了n)
[ ] 匹配[ ]中列举的字符
d 匹配数字,即0-9
D 匹配非数字,即不是数字
s 匹配空白,即 空格,tab键
S 匹配非空白
w 匹配单词字符,即a-z、A-Z、0-9、_
W 匹配非单词字符
1. ‘.‘ : 表示匹配任意一个字符,除n(换行)以外??
? 问题: 看电影 输入电影名称: "速度与*情"
? ?re.match("速度与.情","速度与基情")
? ?re.match("速度与.情","速度与n情")

2.[] : 匹配[ ]中列举的字符
? 问题: 看电影 选择电影名称: "速度与激情9"? 1-9部都可以
re.match("速度与激情[123456789]","速度与激情1")
re.match("速度与激情[1-9]","速度与激情8")
re.match("速度与激情[1-35-9]","速度与激情5")? ?: 除4以外的所有字符

3. d: 表示任意一个数字 ,0-9 中的数字
re.match("速度与激情d","速度与激情9")

4. D: 不是数字的任意一个字符
re.match("速度与激情D","速度与激情*")

5. s : 匹配空格或者tab空格
re.match("速度与激情s","速度与激情? ? ? ? ?")
re.match("速度与激情s","速度与激情#")

6. S : 除了空格tab键的空格以外的所有字符
re.match("速度与激情S","速度与激情u")
re.match("速度与激情S","速度与激情? ? ")

7. w : 匹配单词字符: 0-9,a-z,A-Z,_
? ? python2:单词字符不支持中文,python3支持中文,命名单词或者变量不建议用中文
re.match("w","9")
re.match("w","A")
re.match("w","*")

? ? ? ?8. W : 匹配单词字符以外的所有字符
re.match("W","9")
re.match("W","A")
re.match("W","*")
? ??

四、 匹配多个字符

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

1. {m} : 匹配前一个字符出现m次
? 问题:匹配手机号码, 11位数字??
? re.match("1d{10}","13656789857")
? re.match("1d{10}","1365678985")

2. {m,n}: 匹配前一个字符出现m到n次??
? 问题: 匹配广东电话号码的合法性? 020-56745675,0755-12345678,0756-1234567
? ?re.match("d{3}-d{8}","020-56745795")
? ?re.match("d{3,4}-d{8}","0755-56745795")
? ?re.match("d{3,4}-d{7,8}","0756-5674595")

3. ? : 前一个字符出现1次或者0次
问题: 匹配广东电话号码的合法性? 02056745675,07561234567
re.match("d{3,4}-?d{7,"07565674595")
re.match("d{3,"0756-5674595")
? ??
4. * : 匹配前一个字出现0次或者多次
问题: 把一个文本的内容全部匹配出来?
content="""adslfjaldjgljagganasdiwerierydfgjrn;sdfgrwjtrjg"""?
re.match(".*",content,re.S)
re.match("a*","")
? 注意:?
? ? ?1.? "." 不能匹配换行 n
2. re.S 表示多行匹配

5. + :匹配前一个字符出现1次或者无限次,即至少有1次?
问题:空字符串匹配
? re.match("a+","")
? re.match("a+","aaaaaaaa")


五、匹配开头与结尾
1. ^ : 匹配以xxx开头的字符串
? re.match("^itcast","itcast.cn")
? re.match("itcast","itcast.cn") :match默认就是以itcast开头
? re.match("^itcast","uitcast.cn")
? re.match("itcast","uitcast.cn")

2. $ :匹配以xxx结尾的字符串
? ?问题: 11位手机号码匹配
? ?re.match("1d{10}$","13654678906")
? ?re.match("1d{10}$","13654678906897")

六、案例:
? 1. 案例1: 判断变量名是否合法? ??
? names = ["age1","1age","AG0_","_9age","age_","a9_G2#","a#ffsd"]
? 需求(规则): 变量名合法: 字符由a-z,0-9,_ 组成,但是首字符不能是数字??
ret=re.match("[a-zA-Z_]w*$",name)


参考代码:

import re

def main():
"""需求(规则): 变量名合法: 字符由a-z,_ 组成,但是首字符不能是数字"""
names = ["age1","a#ffsd"]


# 迭代可迭代对象
for name in names:
ret=re.match("[a-zA-Z_]w*$",name)
if ret:
print("变量名%s合法,匹配到的内容%s" %(name,ret.group()))
else:
print("变量名%s不合法"%name)

if __name__ == ‘__main__‘:
main()
?
? ?
? 2. 案例2:?
? ? ?匹配出163的邮箱地址,且@符号之前有4到20位单词字符,例如[email?protected]
? email_list = ["[email?protected]","[email?protected]","[email?protected]","[email?protected]","[email?protected]"]
ret = re.match("w{4,20}@163.com$",email)
??
?
参考代码:
import re

def main():
"""匹配出163的邮箱地址,且@符号之前有4到20位单词字符,例如[email?protected]"""
email_list = ["[email?protected]","[email?protected]","[email?protected]","[email?protected]","[email?protected]"]


# 遍历列表
for email in email_list:
# . 在正则表达式中表示匹配任意一个字符,但是当前需要一个 ".",通过"" 转义符 转回原生(原来、本来的意义,初始的意义)的意义
ret = re.match("w{4,email)
if ret:
print("邮箱%s合法的,匹配的内容是:%s" % (email,ret.group()))
else:
print("邮箱%s不合法" % email)
if __name__ == ‘__main__‘:
main()

? ?
七、匹配分组

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

1. | :匹配左右任意一个表达式
? 问题: 同时匹配出 163和126邮箱的合法性(@符号之前有4到20位单词字符)?
? re.match("w{4,20}@163.com$|w{4,20}@126.com$","[email?protected]")
? re.match("w{4,"[email?protected]")

2. (ab) : 分组
??
? ? 问题1: 匹配多个邮箱地址
? ? ?1. re.match("w{4,20}@(163|126|qq).com$","[email?protected]")
问题2:想取出合法邮箱特定的值,比如取163,126或者邮箱的前缀
In [166]: ret=re.match("(w{4,20})@(163|126|qq).com$","[email?protected]")

In [167]: ret.group()
Out[167]: ‘[email?protected]‘

In [168]: ret.group(0)
Out[168]: ‘[email?protected]‘

In [169]: ret.group(1)
Out[169]: ‘lijun‘

In [170]: ret.group(2)
Out[170]: ‘qq‘

?
3. num : 引用分组num匹配到的字符串
? 问题:需求(规则): html标签配对验证, 比如<h1>dsafagd</h1>,标签必须配对
? re.match("<(w+)>.*</1>","<h1>你好dsafagd</h1>")
? re.match("<(w+)>.*</1>","<h1>你好dsafagd</h2>")
? ??
In [188]: print("1") : "1" : 转义成特殊的符号的,所以需要"1",转出原来的意义即反斜杠 num
??

4. (?P<name>):分组起别名? ?
5. (?P=name) : 引用别名为name分组匹配到的字符串
? 问题:问题4:需求:html标签配对验证, 比如<body><h1>dsafagd</h1></body>
? ? 1. re.match("<(w+)><(w+)>.*</2></1>","<body><h1>你好dsafagd</h1></body>")
2. re.match("<(w+)><(w+)>.*</2></1>","<body><h1>你好dsafagd</h1></bod>")
3. re.match("<(?P<p1>w+)><(?P<p2>w+)>.*</(?P=p2)></(?P=p1)>","<body><h1>你好dsafagd</h1></body>")

? ?

八. re模块的高级用法
a>re.search() :查找,搜索, 当搜索到匹配的内容,则返回
问题:匹配微信公众号文章阅读的次数 :? ?"本文章阅读次数: 9998"
re.search("d+","本文章阅读次数: 9998")
? ? ? ??
b>re.findall() : 找到所有匹配的数据,返回的是list
问题:找到本文的所有数字? ? "本文章阅读次数: 9998次,博客的阅读次数: 50"
ret=re.findall("d+","本文章阅读次数: 9998次,博客的阅读次数: 50")
ret是列表,注意不要使用ret.group()
? ??
c> re.sub() : 替换操作
? ? ?语法:re.sub("正则表达式","替换的内容","查找的字符串或者文本")

问题:将匹配到的阅读次数加1? ? "本文章阅读次数: 9998次,博客的阅读次数: 50"

In [226]: def add(temp):
...:? ? ?strNum=temp.group()
...:? ? ?num=int(strNum)+1
...:? ? ?return str(num)
...:?
...:?


In [227]: ret=re.sub("d+",add,"本文章阅读次数: 9998次,博客的阅读次数: 50")

In [228]: ret
Out[228]: ‘本文章阅读次数: 9999次,博客的阅读次数: 51‘


d> split 根据匹配进行切割字符串,并返回一个列表
? ?语法:re.split("分隔符正则表达式","要分割的文本")
? ?问题: 分离字符串 "wang 18 广州 python"?
? ?In [230]: ret=re.split(" |:|-","wang 18-广州:python")

In [231]: ret
Out[231]: [‘wang‘,‘18‘,‘广州‘,‘python‘]

In [232]: ret[0]
Out[232]: ‘wang‘


九、贪婪和非贪婪
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
? "*",n}" : 特点,取字符的不确定性,存在贪婪与非贪婪,python默认是贪婪的,在"*",n}"后面 加 ? ,把贪婪变为非贪婪
??
? 非贪婪
? *: 0
? ?: 0
? +: 1
? {m,n} :m个
??
? re.search("https://.+?.jpg",img)


十、r的作用
? ?Python中字符串前面加上 r 表示原生字符串
? ?问题:与大多数编程语言相同,正则表达式里使用""作为转义字符,这就可能造成反斜杠困扰
? ?re.match("<(w+)><(w+)>.*</2></1>","<body><h1>你好dsafagd</h1></bod>")
? ?ret=re.match(r"<(w+)><(w+)>.*</2></1>","<body><h1>你好dsafagd</h1><
? ? ...: /body>")
把转义符变为原生的反斜杠

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读