正则表达式

正则表达式

Regular Expression
对输入的字符串进行匹配 看其是否符合某种模式,或提取符合某种模式的字符串

re模块

提供关于正则表达式的工具

re.match(“规则”,“字符串”)x

规则

描述字符

这个规则是单字符匹配 只能匹配一个字符

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

^在方括号中 表示取反操作
[^1-5] 表示 匹配非 1-5中的数

若 要求某一个字符是数字 或者a-g可以写成
[1-9a-z] 当表示两个或条件时 中间什么都不用加

描述数量

匹配多个字符相关的格式

字符功能
*匹配前一个字符出现0次或无限次,a* \d* \s*
+匹配前一个字符出现1次或者无限次 至少一次 a+ \d+ …
?匹配前一个字符出现1次或者0次
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m,n}匹配前一个字符出现从m到n次
re.match("\d*","a")
'''
上式返回的是  ""
是指a前面的匹配到的空字符串
不是None  只有在匹配不成功的时候才返回None
'''

r (raw)原始字符串

当一个字符串用r描述的时候 让字符串的每一个字符都像原来的样子一样

s = r"\nabc"
'''
若输出s不加r 则输出s会带有换行
现在加有r 则会输出原来输入的样子 \nabc
也可以在正则表达式中使用
'''
s = "\\nabc"
#方法1
re.match("\\\\\w*",s)
#方法2 r
re.match(r"\\\w*")

表示边界

字符功能
^匹配字符串的开头
$匹配字符串的结尾
\b匹配一个单词的边界
\B匹配非单词边界
^

在方括号中 ^是取反的意思,但是在外面
表示匹配的字符必须以^后面的字符开头

s = "short"
re.match("^s",s) #表示匹配字符必须以s开头
$

表示匹配的字符串 必须以$前面的字符为结尾

s = "long"
re.match("\w+\w$",s)#表示匹配字符串必须以字符结尾
#必须有机会判断最后一个
re.match("\w+s$",s)
\b

表示匹配一个单词的边界 不占位置
它的前一个字符和后一个字符必须是\w (字母数字)和 \W (非字母数字),即匹配必须出现在 \w (字母数字)和 \W (非字母数字)字符之间的边界上。
It is a dog \bis\b

\B

表示非单词边界 在\B 前或后的字符 下一个字符必须要是字母
bad motherfucker
\Ba\B 表示a 的前后必须有字符

在使用这种有反斜杠的 语法规则时 必须给匹配的规则加r

re.match(r"ba\B","bad")

匹配分组

问题 设置一个正则表达式 匹配0-100的数字

'''
[1-9]\d?$ 包括了1-99
'''
re.match(r"[1-9]\d?$|0|100","100")

'''
[1-9]?\d?$ 表示0-99 
第一个问号  表示第一位为0的时候表示没有出现[1-9]中的数 然后把第一位的0交给\d处理 最后加上了一个终结符$
'''
re.match(r"[1-9]?","0")
字符功能
|匹配|左右任意一个表达式
(ab)将括号中的字符作为一个分组(group)
\num引用第num个分组 匹配到的字符串
(?P<name>)分组起别名
(?P=name)引用别名为name分组匹配到的字符串
(ab) 分组

用() 包裹起来需要查询的字符串 可以在group中获得
看代码

s = "<h1>黑猫警长</h1>"
re.match(r"<h1>.*</h1>",s)
'''
上式会返回关于获取到的字符的所有信息
'''
r = re.match(r"<h1>.*</h1>",s)
r.group()#会返回获取到的字符信息
#获取到的是  <h1>黑猫警长</h1>

'''
若使用括号分组
'''
re.match(r"<h1>(.*)</h1>",s)
'''
上式返回结果与不带括号 的相同
'''
r = re.match(r"<h1>(.*)</h1>",s)
r.group()#只会返回 黑猫警长

#若正则模式中 有多个括号 如
r = re.match(r"(<h1>).*(</h1>)",s)\
r.groups()#显示所有找到的字符串
r.group()
r.group(0)
r.group(1)
r.group(2)
'''
r.group()
r.group(0) 与r.group() 相同 都是返回匹配到的所有分组
r.group(1) 返回匹配到的第一个分组
r.group(2) 返回匹配到的第二个分组
'''
\num

引用第num个分组匹配到的字符串

当利用正则获取到的一个字符串,在正则模式中还需要再次使用的时候 要用到\num

上代码

'''
若要提取web网页标签中的文本信息 
不知道标签的名字 只知道文本内容 在一对标签中
'''

s = "<html><h1>白猫警长</h1></html>"
#常规 有缺陷的提取方法
re.match(r"<.*><.*>.*</.*></.*>",s)
'''
这个方法可以提取到s中的文本内容 但是有缺陷
<html><h1>一只耳</hxxx></h> 这个内容也能提取到 但是是错误的
没有考虑到一对标签的对称
'''
# 使用\num 分组号
re.match(r"<(.*)><(.*)>.*</\2></\1>$",s)
'''
\1 \2 表示 使用前面匹配到的第一个 第二个字符串
'''

#匹配一个邮箱
email = "2601076587@qq.com"
 r = re.match(r"(.+)@(163|126|qq|gmail)\.(com|cn|net)$",email)
'''
用() 包裹起来 |  是因为其中的是整个正则表达式的一部分 并不是一个完整的表达式
'''
r.group(0)
(?P<name>)(?P=name)
s = "<html><h1>白猫警长</h1></html>"

re.match(r"<(?P<key1>.*)><(?P<key2>.*)>.*</?P=key2></?P=key1>",s)


re模块高级用法

search方法

**语法 **re.search(“正则”,“字符串”)
和match相同 只有单词 和作用不同

​ match() 是从第一个开始匹配 若第一个字符 不相匹配的话 就会返回None
search方法 是从第一个开始匹配 若第一个字符 不相配 继续匹配下一个字符 直到找到一个相匹配的或者字符串查找结束 查找完成

findall()

找到文中所有符合条件的字符串 以列表的形式返回

sub()

替换字符串中的值
**语法 **re.sub(“正则”,“替换串”,“查找串”)
sub查找所有符合条件的字符串 然后替换

'''
固定替换串
'''
s ="ba bad bast bai bax"
re.sub(r"\wa","cs",s)

'''
动态替换串
把sub中 放替换串的位置 用一个带有返回值的函数代替
这样替换就不会这么死板了 如对价格进行修改
sub底层相当于调用了一个rearch()方法
会有一个返回值 result
result.group()
'''
s ="java100,python200,c++20,c10"
def replace(result):
    print(result.group())
    r = int(result.group()) + 200
    return r
re.sub(r"\d+",replace,s)

“”" 三个引号 本意是保留原来格式的字符串 但是在.py文件中 只是定义了这个字符串 没有给它命名 所以可以当作注释来看 没有使用它 “”"

split()

以某种规则把字符串进行分割
**语法 **re.split(“规则”,“字符串”)
返回的是一个列表

贪婪模式

正则表达式默认是贪婪模式的
所谓贪婪模式如例子

s = "<p>过山车</p>,<html>倾斜头部 眼神注视</html>"
re.match(r"<.+>",s)#本意是想要匹配一个标签
'''
但是由于默认是贪婪模式,所以遇见第一个>时 不会停下 会一直向后找 直到找到最后一个> 停下来
'''
re.match(r"<.+?>",s)#额外加上一个?就关闭了贪婪模式


'''
又如
 s = "here is a big number 123-124-125-16288"
 r=re.match(r"(.+)(\d+-\d+-\d+-\d+)",s)
 r.group(1)
 '3-124-125-16288'
  r.groups()
('here is a big number 12', '3-124-125-16288')
虽然第一个括号的要求没有包括数字  但是由于是贪婪模式 所以 它会在满足第二个括号要求的前提下 把其他的都给第一个括号  优先满足前面的贪婪模式
第二个括号 要求至少有一个数字 所以就给了第二个括号 一个数字
r=re.match(r"(.+?)(\d+-\d+-\d+-\d+)",s)
r.groups()
('here is a big number ', '123-124-125-16288')
加上一个? 关闭了第一个+的贪婪模式
但是第二个+的贪婪模式并没有关闭 所以会尽可能满足第二个+ 至少有一个数字  最多没有限制
所以分配了 123
'''

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值