python3 正则表达式 re (不全 用到哪个写哪个)

2023.10.31

之前只是知道有这么个东西,上学没好好学,之前工作也是边查边用,用完就忘。
最近空窗期备考华子刷题有用到,顺带整理和知识补足。
正则的东西有点多,从零开始理解,用到哪些就写到这来。

正则表达式,一个特殊的字符序列,用来描述一种模式,或者说成是规则。
然后可以对字符串进行操作,来判断字符串是否符合这种模式,
或者去查找字符串内是否包含满足这种模式的字符串,甚至进行替换。

正则表达式,这个序列的写法规则及对应的概念和意义:
        字符集合设定: 用中括号括起 [abc123] 来表示其中任一字符
                中划线 - :[a-zA-Z] 来表示 所有的大小写字母
                非 ^ :[^a-zA-Z]    写在中括号内开头 表示除了中括号内的字符之外的任意字符
                           [a-z^A-Z]    写在其他地方,就只表示它本身而没有取非的意思
                数字 \d :  等同于[0-9]
                非数字 \D : 等同于[^0-9]
                字母数字 \w : 等同于[a-zA-Z0-9]
                非字母非数字 \W : 等同于[^a-zA-Z0-9] 
        重复:用以表示前面紧挨着的字符集合的次数
                0+次  *  : 表示0次或以上
                1+次  + : 表示1次或以上
                0,1次 ? : 表示0次或者1次, 要么0要么1
                精确次数  {m,n}: 表示最少m次到最多n次之间
        组: 用以表示正则序列内的一部分
                用圆括号括起来 ( ) 即为一组
                ([a-zA-Z]+)(\d+) 这个正则序列内有两个组
                        组号0表示正则序列本身
                        组号1表示字母
                        组号2表示数组

正则的使用:
        1. 第一题用到的是匹配(查找)
                查找,在这里写两个方法,re.match() 和 re.search(),先看代码

import re
s = 'Seven77'
matcher = re.match(r'([a-zA-Z]+)(\d+)', s)
print(matcher)             # <re.Match object; span=(0, 7), match='Seven77'>
print(matcher.group(0))    # Seven77
print(matcher.group(1))    # Seven
print(matcher.group(2))    # 77
print(matcher.group(3))    # IndexError: no such group
import re
s = 'Seven77'
searcher = re.search(r'([a-zA-Z]+)(\d+)', s)
print(searcher)            # <re.Match object; span=(0, 7), match='Seven77'>
print(searcher.group(0))   # Seven77
print(searcher.group(1))   # Seven
print(searcher.group(2))   # 77
print(searcher.group(3))   # IndexError: no such group

两个方法都是查找匹配,并且可以用.group()来取到,匹配成功的部分对应的组内的值
区别见下例:

 

import re
s = '0Seven77'
matcher = re.match(r'([a-zA-Z]+)(\d+)', s)
print(matcher)             # None
print(matcher.group(0))    # AttributeError: 'NoneType' object has no attribute 'group'
print(matcher.group(1))    # AttributeError: 'NoneType' object has no attribute 'group'
print(matcher.group(2))    # AttributeError: 'NoneType' object has no attribute 'group'
import re
s = '0Seven77'
searcher = re.search(r'([a-zA-Z]+)(\d+)', s)
print(searcher)             # <re.Match object; span=(1, 8), match='Seven77'>
print(searcher.group(0))    # Seven77
print(searcher.group(1))    # Seven
print(searcher.group(2))    # 77

两者查找匹配,都是从前往后,但区别在于,如果match一开始没有查到满足的字串,则返回None
而search则会尝试向后查找,若有则返回。若无则返回None。

import re
ss = '0Seven'
searcher = re.search(r'([a-zA-Z]+)(\d+)', ss)
print(searcher)             # None
print(searcher.group(0))    # AttributeError: 'NoneType' object has no attribute 'group'
print(searcher.group(1))    # AttributeError: 'NoneType' object has no attribute 'group'
print(searcher.group(2))    # AttributeError: 'NoneType' object has no attribute 'group'

所以一般用完match()或者search()后,在取值之前要进行是否为None的判断。代码暂略。

知道这几块就可以解第一道报文重排序的题了。

==========================分割线=======================================

多带一嘴关于re.compile() 上代码

import re
s1 = 'eg11'
s2 = 'eg22'
s3 = 'eg33'
matcher1 = re.match(r'([a-zA-Z]+)(\d+)', s1)
matcher2 = re.match(r'([a-zA-Z]+)(\d+)', s2)
matcher3 = re.match(r'([a-zA-Z]+)(\d+)', s3)

此时正则被写了三次,虽说可以cv但还是有点麻烦,因此介入compile()

import re
s1 = 'eg11'
s2 = 'eg22'
s3 = 'eg33'
reg = re.compile(r'([a-zA-Z]+)(\d+)')
matcher1 = reg.match(s1)
matcher2 = reg.match(s2)
matcher3 = reg.match(s3)

 两种写法完全等效,同样可以用于search()和其他方法

参考文章:

python | 史上最全的正则表达式_python 正则表达式-CSDN博客

华为OD机试 - 报文重排序(Java & JS & Python & C)-CSDN博客

==========================分割线=======================================

2023.11.08

遇到了正则替换,就再来写一下关于re.sub(),把匹配上的部分进行替换。
可以看一下参考那篇文章

简单说起就是要有三个参数,1.正则 2.替换成什么 3.原字符串
更高级的可以声明做几次替换, 以及是否忽略大小写什么的

先记最质朴的:

import re
s = '[10,20,5]'
ret = re.sub(r'[\[\]]', '', s)
print(ret)                       # 10,20,5

或者

import re
s = '[10,20,5]'
reg = re.compile(r'[\[\]]')
ret = reg.sub('', s)
print(ret)                       # 10,20,5

顺带一提,如果正则写的时候没写原样字符标识r, 会抛一个警告:
SyntaxWarning: invalid escape sequence '\['
是在提示当前代码中的反斜线 \ 被视为转义字符
使用正则时候大多都要写r的,不然有时会很迷糊

以上。

        

参考文章:

re.sub()用法详解_IT之一小佬的博客-CSDN博客
SyntaxWarning: invalid escape sequence ‘\p‘-CSDN博客


==========================分割线=======================================

2024.01.05   关于符号与贪婪

首先是字符点 '.'  用来匹配除 "\n" 之外的任何单个字符。
(要匹配包括 '\n' 在内的任何字符,请使用如 '[.\n]' 的模式)
(当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符)
(如果使用了 ’S’ 选项,匹配包括 ’/n’ 的所有字符。)

其次是字符 '*', '+', '?'   此三者用来表明重复次数
*     表示前置规则重复 0次或1次或多次
+    表示前置规则重复 1次或多次
?    表示前置规则重复  0次或1次
+ 与 * 二者的后面,可以加 ? 来表示非贪婪

贪婪,顾名思义,尽可能多的
+ 本身,表示一次或多次匹配,在默认的贪婪模式下,会匹配尽可能多的字符
* 同理
这时引出, +?   表示一次或多次匹配,但是不贪婪,会匹配尽可能少的字符
*?   同理

下面的示例是搬运,先附原文链接,原作者写的太好了,连我都看懂了!
https://www.cnblogs.com/wjx-blog/p/12123279.html

1. .*
. 表示 匹配除换行符 \n 之外的任何单字符,*表示零次或多次。所以.*在一起就表示任意字符出现零次或多次。没有?表示贪婪模式。比如a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
又比如模式src=`.*`, 它将会匹配最长的以 src=` 开始,以`结束的最长的字符串。用它来搜索 <img src=``test.jpg` width=`60px` height=`80px`/> 时,将会返回 src=``test.jpg` width=`60px` height=`80px`

2. .*?
?跟在*或者+后边用时,表示懒惰模式。也称非贪婪模式。就是匹配尽可能少的字符。就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
又比如模式 src=`.*?`,它将会匹配 src=` 开始,以 ` 结束的尽可能短的字符串。且开始和结束中间可以没有字符,因为*表示零到多个。用它来搜索 <img src=``test.jpg` width=`60px` height=`80px`/> 时,将会返回 src=``。

3. .+?
同上,?跟在*或者+后边用时,表示懒惰模式。也称非贪婪模式。就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
a.+?b匹配最短的,以a开始,以b结束的字符串,但a和b中间至少要有一个字符。如果把它应用于ababccaab的话,它会匹配abab(第一到第四个字符)和aab(第七到第九个字符)。注意此时匹配结果不是ab,ab和aab。因为a和b中间至少要有一个字符。
又比如模式 src=`.+?`,它将会匹配 src=` 开始,以 ` 结束的尽可能短的字符串。且开始和结束中间必须有字符,因为+表示1到多个。用它来搜索 <img src=``test.jpg` width=`60px` height=`80px`/> 时,将会返回 src=``test.jpg`。注意与.*?时的区别,此时不会匹配src=``,因为src=` 和 ` 之间至少有一个字符。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值