在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块来操作,名字为re
import re
(一) 三种基本方法 match,search和findall
在re模块中,通常使用三种方法,match,search和findall,下面对这三种方法进行简单的介绍: (1).match方法 re.match 尝试从字符串的起始位置匹配一个模式,匹配成功则返回的是一个匹配对象(这个对象包含了我们匹配的信息),如果不是起始位置匹配成功的话,match()返回的是空, 注意:match只能匹配到一个**
下面来看代码理解
s = 'pythonasdfasfdpythonsd6d6'
result = re.match('python', s)
print(result) #
print(result.span()) # (0, 6)
print(result.group()) # python
1.通过span()提取匹配到的字符下标 2.通过group()提取匹配到的内容 而s字符串中有3个python的存在,match只能匹配到一个
下面我们改变一下s,得到不一样的结果
s = '1python123python666python888'
result = re.match('python', s)
print(result) #None
因为match从字符串的起始位置开始匹配,这里起始的第一个字符为1,所以匹配失败返回None. 那么我们要如何才能匹配到字符串中间我们想要的部分呢,这个时候就用到了search函数
(2).search方法 re.search 扫描整个字符串,匹配成功则返回的是一个匹配对象(这个对象包含了我们匹配的信息) 注意:search也只能匹配到一个,找到符合规则的就返回,不会一直往后找 同样的,search也只能匹配到一个. 代码如下
s = '1pythonasdfpython8sdf8123sd'
result = re.search('python', s)
print(result) #
print(result.span()) # (1, 7)
print(result.group()) # python
当然,若是都找不到则返回None值
s = '1python1d2sd3python66sdgf6python83248dgd'
result = re.search('python98', s)
print(result) # None
*search方法虽然解决了match的从头匹配的弊端,但它也只能匹配到一个,这个时候我们就可以使用findall方法了 *
(3).findall方法: 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表
s = '1python1sd2e3ertpythoertert8'
result = re.findall('python', s)
print(result) # ['python', 'python', 'python']
上面的三种方法看上去只能匹配到简单的字符串,也许我们觉得用一般的方法也可以办到: 比如字符串的index方法(也可以用循序)
print(s.index('python')) # 1 print(s.index('python', 2)) # 10 print(s.index('python', 11)) # 19 那么正则表达式应该用在什么地方呢:
判断用户注册帐号是否满足格式 抓取页面中特定部分数据 判断用户提交的邮箱的格式是否正确 等等等等 那么我们就要了解元字符
(二) 正则表达式对象的常用方法
rx.findall(s,start, end): 返回一个列表,如果正则表达式中没有分组,则列表中包含的是所有匹配的内容, 如果正则表达式中有分组,则列表中的每个元素是一个元组,元组中包含子分组中匹配到的内容,但是没有返回整个正则表达式匹配的内容 rx.finditer(s, start, end): 返回一个可迭代对象 对可迭代对象进行迭代,每一次返回一个匹配对象,可以调用匹配对象的group()方法查看指定组匹配到的内容,0表示整个正则表达式匹配到的内容 rx.search(s, start, end): 返回一个匹配对象,倘若没匹配到,就返回Nonesearch()方法只匹配一次就停止,不会继续往后匹配 rx.match(s, start, end): 如果正则表达式在字符串的起始处匹配,就返回一个匹配对象,否则返回None rx.sub(x, s, m): 返回一个字符串。每一个匹配的地方用x进行替换,返回替换后的字符串,如果指定m,则最多替换m次。对于x可以使用/i或者/g
rx = re.compile(r"(\d)[a-z]+(\d)")
s = "ab12dk3klj8jk9jks5"
result = rx.split(s)
返回['ab1', '2', '3', 'klj', '8', '9', 'jks5']
rx.flags() 正则表达式编译时设置的标志rx.pattern() 正则表达式编译时使用的字符串
(四)匹配对象的属性与方法
m.group(g, ...) 返回编号或者组名匹配到的内容,默认或者0表示整个表达式匹配到的内容,如果指定多个,就返回一个元组 m.groupdict(default) 返回一个字典。字典的键是所有命名的组的组名,值为命名组捕获到的内容 如果有default参数,则将其作为那些没有参与匹配的组的默认值。 m.groups(default) 返回一个元组。包含所有捕获到内容的子分组,从1开始,如果指定了default值,则这个值作为那些没有捕获到内容的组的值 m.lastgroup() 匹配到内容的编号最高的捕获组的名称,如果没有或者没有使用名称则返回None(不常用) m.lastindex() 匹配到内容的编号最高的捕获组的编号,如果没有就返回None。 m.start(g) 当前匹配对象的子分组是从字符串的那个位置开始匹配的,如果当前组没有参与匹配就返回-1 m.end(g) 当前匹配对象的子分组是从字符串的那个位置匹配结束的,如果当前组没有参与匹配就返回-1 m.span() 返回一个二元组,内容分别是m.start(g)和m.end(g)的返回值 m.re() 产生这一匹配对象的正则表达式 m.string() 传递给match()或者search()用于匹配的字符串 m.pos() 搜索的起始位置。即字符串的开头,或者start指定的位置(不常用) m.endpos() 搜索的结束位置。即字符串的末尾位置,或者end指定的位置(不常用)
(三) 字符串匹配细节
1. re.match
单字符匹配
以下字符,都匹配单个字符数据。且开头(从字符串0位置开始)没匹配到,即使字符串其他部分包含需要匹配的内容,.match也会返回none
单字符匹配
字符功能备注.匹配任意一个字符(除了 \n )[ ]匹配 [ ] 中列举的字符\d匹配数字,即 0 ~ 9\D匹配非数字,即不是数字\s匹配空白,即空格,tab键\S匹配非空白\w匹配单词字符,即a-z, A-Z, 0-9, _ (下划线)\W匹配非单词字符
例如:
. 匹配任意一个字符 使用几个点号就代表几个字符
import re a = re.match('..','testasdtest') print(a.group()) #输出te b = re.match('ab.','testasdtest') print(b) #返回none,因为表达式是以固定的ab开头然后跟上通配符. 所以必须要先匹配上ab才会往后进行匹配
\d 匹配数字 一个\d代表一个数字。开头没匹配到,即使字符串其他部分包含需要匹配的内容,.match也会返回none
import re a = re.match('\d\d','23es12testasdtest') print(a) b = re.match('\d\d\d','23es12testasdtest') print(b) #要求匹配三个数字,匹配不到返回none c = re.match('\d','es12testasdtest') print(c) #起始位置没有匹配成功,一样返回none
\D 匹配非数字 开头没匹配到,即使字符串其他部分包含需要匹配的内容,.match也会返回none
import re a = re.match('\D','23es12testasdtest') print(a) #开头为数字所以返回none b = re.match('\D\D','*es12testasdtest') print(b) #返回*e \s 匹配特殊字符,如空白,空格,tab等
代表数量的元字符
字符功能备注*匹配前一个字符出现0次或者无数次,即可有可无+匹配前一个字符出现1次或者无数次,即至少有1次?匹配前一个字符出现1次或者0次,即要么1次要么没有{m}匹配前一个字符出现m次{m,}匹配前一个字符至少出现m次{m,n}匹配前一个字符出现m到n次
匹配边界
字符功能备注^匹配字符串开头$匹配字符串结尾\b匹配一个单词的边界\B匹配非单词边界
匹配分组
字符功能备注|匹配左右任意一个表达式(ab)将括号中字符作为一个分组 \num引用分组num匹配到的字符串(?P
re.s findall中另外一个属性re.S
在字符串a中,包含换行符\n,在这种情况下
如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。 而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。 如下要寻找test.*123的数据,因为test和123在不同的行,如果没加re.s的话,他会在每一个进行匹配查找而不是将字符串作为一个整体进行查找
import re a = """aaatestaa aaaa123""" print(re.findall(r'test.*123',a)) print(re.findall(r'test.*123',a,re.S))
sub 查找字符串中所有相匹配的数据进行替换
sub(要替换的数据,替换成什么,要替换的数据所在的数据)
import re print(re.sub('php','python','php是世界上最好的语言——php')) #输出 "python是世界上最好的语言——python"
split 对字符串进行分割,并返回一个列表
import re s = "itcase,java:php-php3;html" print(re.split(r",",s)) #以,号进行分割 print(re.split(r",|:|-|;",s)) #以,或者:或者-或者;进行分割 print(re.split(r",|:|-|%",s)) #找不到的分隔符就忽略
贪婪与非贪婪 python里的数量词默认是贪婪的,总是尝试尽可能的匹配更多的字符。python中使用?号关闭贪婪模式
如
import re print(re.match(r"aa\d+","aa2323")) #会尽可能多的去匹配\d print(re.match(r"aa\d+?","aa2323")) #尽可能少的去匹配\d
“输出:
”
import re s = "this is a number 234-235-22-423" # 1.贪婪模式 resule = re.match(r"(.+)(\d+-\d+-\d+-\d)",s) #我们本想数字和字母拆解成两个分组 print(resule.groups()) #('this is a number 23', '4-235-22-4')但我们发现输出的结果中23的数字竟然被弄到前面去了 #因为+它会尽可能多的进行匹配,\d,只需要一个4就能满足,所以前面就尽可能多的匹配 # 2.关闭贪婪模式 #在数量词后面加上 ?,进入非贪婪模式,尽可能少的进行匹配 result = re.match(r"(.+?)(\d+-\d+-\d+-\d)",s) print(result.groups()) #('this is a number ', '234-235-22-4')
“输出:
('this is a number 23', '4-235-22-4')
('this is a number ', '234-235-22-4')
”
&&&&&&&&&&&&&:
key = "威胁" a = """
“结果:
很抱歉,由于您访问的URL有可能对网站造成安全威胁,您的访问被阻断。
”
在html中,“ ”表示空格
其中“&”在html用做转义。
例如:&表示“&”;<表示“<”;>表示“>”等等。
“ (注意此字母必须小写,方可空格)”表示非换行空格;表示文件路径时使用符号“/”分隔,文件名及路径描述可用双引号也可不用引号括起。
2. python中的group方法
group()在正则表达式中用于获取分段截获的字符串,解释如下代码(代码来自网络):
import re a = "123abc456" print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123 print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456
可以看出,正则表达式按照数字-字母-数字的顺序来获取相应字符串,那么分别就是“数字(group(1))--字母(group(2))--数字(group(3))”的对应关系,
其中,group(0)和group()效果相同,均为获取取得的字符串整体。
group和groups是两个不同的函数。 一般,m.group(N) 返回第N组括号匹配的字符。 而m.group() == m.group(0) == 所有匹配的字符,与括号无关,这个是API规定的。
m.groups() 返回所有括号匹配的字符,以tuple格式。 m.groups() == (m.group(0), m.group(1), ...)
group()和groups() 参考:
python中group方法以及与groups的区别_python groups-CSDN博客
python group与groups 详解以及区分_代码group是什么意思-CSDN博客
group与groups:
match和search匹配的返回结果都是对象,如果要获取对应字符串,需要使用group(num) 或 groups() :
group(num=0):
直接调用则返回整个匹配结果,
如果group里面有参数:group(0)代表整个匹配结果,group(1) 列出第一个分组匹配部分,group(2) 列出第二个分组匹配部分,group(3) 列出第三个分组匹配部分,以此类推。
groups()
以元组返回所有分组匹配的字符
附加:
start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
span([group]) 方法返回 (start(group), end(group))。
没有子组的情况下是返回整个匹配结果的start和end:
只有有group方法的查找方式的结果才有start,end,span,而findall是没有的
参考阅读
本文由 用户 于 2024-02-11 发布在 金钥匙,如有疑问,请联系我们。
本文链接:https://www.51969.com/post/18526201.html
发表评论