正则表达式写法整理
写爬虫的时候因为正则表达式写的有问题除了一些bug,翻了翻以前记的一些相关的笔记,打算总结一番,当然还是以python为例来写。
所以就直接把python中的re模块的基本使用和正则表达式的匹配规则放在一起了:
匹配单个字符
匹配特定字符串
text = "abc"
ret = re.match('a',text) #写a就行 写b就不行,因为match只从头查找,用match查到的只能是最前面的
print(ret.group())#记住 match返回的是个分组,用match就用group()提取
输出结果:a
re.match模块,从头开始匹配,如果一开始就无法匹配,则匹配失败。
匹配任意的字符(除了'\n'),用 ‘.’
text1 = "\nabc" #反斜杠n匹配不了,"."唯一不能代表的就是这个换行符
text2 = "+abc"
# res1 = re.match('.',text1)
res2 = re.match('.',text2)
# print(res1.group())
print(res2.group())
输出结果:+
如果运行注释部分,则报错,因为‘\n’无法匹配。
补充,加上re.DOTALL。表示’.’也可以代表换行符
有了re.DOTALL就说明’.’就是可以匹配一切。
从下面起,颜色相同的可以对照着看。
匹配任意的数字,用‘\d’
text = "abc"#不可以匹配到
text = "1abc"
res = re.match('\d',text) #从最前面开始,且只匹配一个数字
print(res.group())
输出结果:1
匹配任意非数字,用‘\D’——大小写之间就是意义相反
text = "1abc" #不可以匹配到
text = "abc"
res = re.match('\D',text) #大写\D匹配一切非数字
print(res.group())
输出结果:c
匹配空白字符,用‘\s’ (空白字符包括换行符、制表符、回撤、空格等)
text = " abc" #都可以
text='\nabc'
text='\tabc'
text='\rabc'
res = re.match('\s',text)
print("=====") #加上等号只为说明确实有输出
print(res.group())
print("=====")
输出结果:
=====
=====
非空白字符,用‘\S’——大小写之间意义相反
text = "\nabc" #不可以匹配到
text="abc"
res = re.match('\S',text)
print(res.group())
输出结果:a
匹配的是a-z和A-Z以及数字和下划线,用‘\w’
text = "+abc" #无法匹配到
text = "abc"
res = re.match('\w',text)
print(res.group())
输出结果:a
这里\w能匹配到的东西,可以这样理解:在程序设计时定义的合法变量名都包含哪些,\w就包含哪些。
匹配‘\w’之外的一切,用’\W’
text = "abc"#无法匹配到
text='+abc'
res = re.match('\W',text)
print(res.group())
输出结果:+
匹配‘或’的关系,用中括号[]
中括号的意思是,只要满足括号内的任何一个,就算成功。
text = 'abc'#两个都可以匹配
text = "1abc"
res = re.match('[1a]',text) #要么匹配1要么匹配b,有一个就行
print(res.group())
输出结果:1
因此,[0-9]可以匹配0至9的任意一个数字,[^0-9]可以匹配除了0-9中的数字之外的符号。即[0-9]等价于\d,[^0-9]等价于\D。
同理:[a-zA-Z0-9_]等价于\w,[^a-zA-Z0-9_]等价于\W。
此外,表示或还可以用‘|’符号,所以[1a]等价于1|a
匹配多个字符
匹配0次或多次字符,用‘*’
text = "+abc"
res = re.match('\D*',text)
print(res.group())
text = "+abc"
res = re.match('\w*',text)
print('====')
print(res.group()) #匹配到0个,不会报错
print('====')
输出结果:
+abc
====
====
值得一提的是,这里用*后没有?,默认是贪婪匹配,所以第一个输出直接匹配到了最后。贪婪与非贪婪,等一会再小总结一下。
匹配1次或多次字符,用‘+’
text = "1abc"
res = re.match('\w+',text)
print(res.group())
text = "+abc"
res = re.match('\w+',text) #一个也匹配不到,+号会报错
print(res.group())
输出结果:
1abc
报错
匹配0次或1次字符,用‘?’
text = "1abc"
res = re.match('\w?',text)
print(res.group())
text = "+abc"
res = re.match('\w?',text)
print('====')
print(res.group()) #返回一个空的,不会报错
print('====')
输出结果:
1
====
====
突然发现一个小规律:可以匹配0次的符号,就不会出现报错的风险。
匹配特定数量n个字符,用大括号‘{n}’
text = "1abc"
res = re.match('\w{2}',text) #想匹配几个匹配几个
print(res.group())
#{m}:匹配m个字符:
text = "+abc"
res = re.match('\w{2}',text) #现在就不满足了
print(res.group())
输出结果:
1a
报错
匹配特定数量范围的m到n个字符,用{m,n},尽可能接近n
text = "1abc+"
res = re.match('\w{1,3}',text) #有三个就三个,没有就2,最少1个也行,再没有就报错
print(res.group())
text = "1a+bc+"
res = re.match('\w{1,3}',text)
print(res.group())
text = "+1abc+"
res = re.match('\w{1,3}',text) #无法匹配
print(res.group())
输出结果:
1ab
1a
报错
一些额外补充
以...开头:用‘^’符号。
text = "hello world"
res = re.search("world",text)
print(res.group())
res = re.search("^world",text) #找不到, 所以search加上^就可以当match用,match可以永远不用~
print(res.group())
输出结果:
world
报错
这里用的是re.search方法,和之前的match的区别在于,它不会默认从头开始搜索。但是当search中的正则表达式加上^符号时,即希望收到以‘^’后字符串为开头的结果,此时就相当于match方法了。即 search+‘^’等价于match。
以...结尾:用‘$’符号
text = "hello world"
res = re.search("world$",text)
print(res.group())
res = re.search("hello$",text) #无法匹配,因为text不是以hello结尾
print(res.group())
输出结果:
world
报错
贪婪模式和非贪婪模式
text = "12345"
res = re.search("\d+",text) #+后没有?,贪婪模式,尽可能多地匹配
print(res.group())
res = re.search("\d+?",text) #有?,非贪婪,尽可能少地匹配
print(res.group())
输出结果:
12345
1
如果要匹配目标字符串中的’$’等“专用字符”,可以加上\来转义
text = "you give me $10,I give you $100"
res = re.findall("\$\d+",text)
print(res)
输出结果:
['$10', '$100']
这里用到了re.findall(),我感觉这个是最好用的,可以直接返回所有匹配到的结果,并且放进一个列表。
当然,用search方法也能返回多个,但得自己把语句写全,然后在需要的地方加括号选取所需,然后用group提取。
Search与findall的区别就在于findall可以全局地去匹配并且返回多个,search只能匹配第一个,只不过在匹配到的第一个中,我们可以去加括号提取多个,所以search要匹配多个得把语句写全面:
text = "you give me $10,I give you $100"
res = re.search('.+(\$\d+).+(\$\d+)',text)
print(res.groups())#获取所有的括号内容
print(res.group())# group()/group(0):获取所有匹配到的,不止括号内的
print(res.group(0))
print(res.group(1))#匹配第一个括号内容
print(res.group(2))#匹配第二个括号内容
输出结果:
('$10', '$100')
you give me $10,I give you $100
you give me $10,I give you $100
$10
$100
re.sub方法,通过正则匹配,再替换。
text = "you give me $10,I give you $100"
new_text = re.sub(r',','\n',text) #把逗号都替换成\n,三个参数
print(text)
print(new_text)
输出结果:
you give me $10,I give you $100
you give me $10
I give you $100
re.split方法,顾名思义,可以按正则去匹配要分割的符号。
text = "you give me $10,I give you $100"
res = re.split(r' |,',text) #返回一个列表 按空格或逗号分隔
print(res)
输出结果:
['you', 'give', 'me', '$10', 'I', 'give', 'you', '$100']
re.compile方法,
import re
text = 'you give me $10,I give you $10.0'
complete=re.compile(r"""
\d+
\.?
\d*
""",re.VERBOSE)
res=re.findall(complete,text)
print(res)
输出结果:
['10', '10.0']
上面用了compile来存储我们的正则表达式,因为这里我们把它写成了多行,要想让re模块识别,就必须加上re.VERBOSE来说明。所以通过这个例子我们可以知道,有时候一行正则表达式写不完,可以用这种方式给他分开。 当然这里是故意这么写做个参考而已,这点正则语句放在一行里写也是完全ok的。
这种就等价于:
import re
text = 'you give me $10,I give you $10.0'
res=re.findall(r"""
\d+
\.?
\d*
""",text,re.VERBOSE)
print(res)
结果也是['10', '10.0']。
正则表达式看多了头都有点痛了....先整理到这些吧,基本基础应该都覆盖了,有必要的以后补充~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了