开篇絮絮念
最近接触到了正则表达式这一概念,但是还不熟悉,借此整理所学知识并且分享给大家,大家看到有兴趣的话欢迎留言评论哦。
正则表达式概念
正则表达式:也称规则表达式(Regular Expression),在程序中经常会缩写为regex或者regexp,专门用于进行文本检索、匹配、替换等操作的一种技术。
注意:正则表达式是一种独立的技术,不是某种编程语言独有的。
Python中的正则表达式
Python中操作正则表达式需要用到re模块,里面提供了各种正则表达式的处理函数。
import re # 使用正则表达式操作前先导入re模块
正则表达式相关操作
(一)字符查询匹配函数
函数 | 描述 |
re.match(reg, info) | 用于在开始位置匹配目标字符串info中符合 正则表达式reg的字符,匹配成功会返回一个 match对象,匹配不成功则返回None |
re.search(reg, info) | 扫描整个字符串,匹配目标字符串info中符合 正则表达式reg的字符,匹配成功会返回第一个 match对象,匹配不成功则返回None |
re.findall(reg, info) | 扫描整个字符串并匹配目标字符串info中符合 正则表达式reg的字符,将匹配的字符串全部提取 并放置在一个列表中返回 |
re.fullmatch(reg, info) | 扫描整个字符串,如果整个字符串都包含在正则表达式表示的范围中, 返回整个字符串,否则返回None |
re.finditer(reg, info) | 扫描整个字符串,将匹配到的字符保存在一个可以遍历的列表中 |
import re
string = "I'm B+Tree, so handsome!"
ret = re.match("Tree", string)
print(ret) # None 因为开头不是Tree
# re.search()
ret1 = re.search("handsome", string)
print(ret1) # <re.Match object; span=(15, 23), match='handsome'>
# re.findall()
ret2 = re.findall("so", string)
print(ret2) # ['so', 'so']
# re.finditer()
ret3 = re.finditer("e", string)
print(ret3) # <callable_iterator object at 0x0000000001EA8630>
# re.fullmatch()
ret4 = re.fullmatch("handsome", string)
ret5 = re.fullmatch(".*", string)
print(ret4, ret5) # None <re.Match object; span=(0, 24), match="I'm B+Tree, so handsome!">
(二)字符串拆分替换函数
函数 | 描述 |
re.split(reg, string) | 使用指定的正则表达式reg匹配字符, 将字符串string拆分成一个字符串列表。 |
re.sub(reg, repl, string) | 使用指定的字符串repl来替换 目标字符串string中匹配正则表达式reg的字符 |
import re
string = "I'm B+Tree, so handsome!"
# re.split() 指定字符将目标字符串拆分
res = re.split(" ", string) # 使用空格将字符串拆分
print(res) # 输出:["I'm", 'B+Tree,', 'so', 'handsome!']
# re.sub() 使用指定的字符串repl来替换目标字符串string中匹配正则表达式reg的字符
res1 = re.sub("e", "H", string)
print(res1) # 输出:I'm B+TrHH, so handsomH!
(三)正则表达式元字符
使用正则表达式时,用到一些包含特殊含义的字符,用于比试字符串中一些特殊的位置。
常用元字符
元字符 | 描述 |
^ | 表示匹配字符串的开头位置的字符 |
$ | 匹配结尾位置,该符号前面的字符 |
. | 表示匹配任意字符 |
\d | 匹配一个数字字符 |
\D | 匹配一个非数字字符 |
\s | 匹配一个空白字符,包括空格和tab |
\S | 匹配一个非空白字符 |
\w | 匹配一个数字、字母、下划线中的任意一个字符 |
\W | 匹配非数字、非字母、非下划线中的任意一个字符 |
\b | 匹配一个单词的边界 |
\B | 匹配的不是单词的开头或者结束的位置 |
import re
string = "I'm B+Tree, so handsome!"
# ^:匹配字符串开头的位置,不能与match一起使用,逻辑重复了
res = re.search(r"^I", string)
res1 = re.search(r"^m", string)
print(res, res1) # 输出:<re.Match object; span=(0, 1), match='I'> None
# $:匹配字符串结尾的位置
lst = ["you are so cute", "you are handsome"]
for i in lst:
if re.findall(r"some$", i):
print(i) # you are handsome
# .表示匹配任意一个字符
res2 = re.match(".", string)
print(res2) # <re.Match object; span=(0, 1), match='I'>
# \d\D 表示匹配一个数字字符且紧跟着一个非数字字符
string1 = "他才13岁了,但是长得像20岁"
res3 = re.findall("\d\D", string1)
print(res3) # ['3岁', '0岁']
# \s\S 表示匹配一个空白字符且紧跟着一个非空白字符
string2 = "long time no see"
res4 = re.search("\s\S", string2)
print(res4) # <re.Match object; span=(4, 6), match=' t'>
# \w\W 匹配一个数字/字母/下划线且紧跟着一个非数字/字母/下划线的字符
string4 = "123456789@qq.com"
res5 = re.findall("\w\W", string4)
print(res5) # ['9@', 'q.']
# \b匹配一个单词边界,使用\b时最好使用r"",规定是元组字符,否则\b不生效,因为\b也是转义字符:退格(BS) ,将当前位置移到前一列
string5 = "hello world"
res6 = re.findall(r"\bhe.*\b", string5) # 边界最好两边都添加一下
print(res6) # ['hello world']
(四)正则表达式中的量词
量词:用于限定字符出现数量的关键字
量词 | 描述 |
x* | 用于匹配*号前的字符,可以出现0次或者多次 |
x+ | 用于匹配+号前的字符,可以出现1次或者多次 |
x? | 用于匹配?号前的字符,可以出现0次或者1次,问号必须是英文输入法 |
x{n} | 用于匹配{n}号前的字符,出现n次 |
x{m,n} | 用于匹配{m,n}号前的字符,可以出现最少m次,最多n次,{m,n}不能存在空格 |
x{n,} | 用于匹配{n,}号前的字符,至少出现n次 |
import re
love_story = "Romeo take me somewhere we can be alone\
I'll be waiting all there's left to do is run\
You'll be the prince and I'll be the princess\
It's a love story\
Baby just say yes\
Romeo save me"
# 查找非空格且以ll结尾的单词 \s匹配空格 \S匹配非空格
res = re.findall(r"\S+ll", love_story)
print(res) # ["I'll", 'all', "You'll", "I'll"]
# 查找以s开头的单词,s前是空格,s后是非空格
res1 = re.findall(r"\ss\S+", love_story)
print(res1) # [' somewhere', ' story', ' say', ' save']
# 查找有l的单词
res2 = re.findall(r"\S*l{1,}\S*", love_story)
print(res2) # ['alone', "I'll", 'all', 'left', "You'll", "I'll", 'love']
# 查找一个以R开头,以eo结尾的单词
res3 = re.match("R.*?eo", love_story)
print(res3.group()) # Romeo
(五)正则表达式范围匹配
在正则表达式中,针对字符的匹配,除了快捷的元字符串的匹配,还有另一种使用方括号进行的范围匹配方式,具体如下
范围 | 描述 |
[0-9] | 用于匹配一个0-9之间的数字,等价于\d |
[^0-9] | 用于匹配一个非0-9之间的数字,等价于\D,^在方括号中表示取反 |
[3-6] | 用于匹配一个3-6之间的数字 |
[a-z] | 用于匹配一个a-z之间的数字 |
[A-Z] | 用于匹配一个A-Z之间的数字 |
[a-zA-Z] | 用于匹配一个a-z或者A-Z之间的数字,匹配任意一个字母 |
[a-zA-Z0-9] | 用于匹配一个0-9或者a-z或者A-Z之间的数字 ,等价\w |
[^a-zA-Z0-9] | 用于匹配一个非0-9或者a-z或者A-Z之间的数字 ,等价\W |
import re
msg = "Hello, the count of today is 800"
# 匹配字符串中的所有数字
print(re.findall(r"[0-9]+", msg)) # ['800']
# 匹配字符串中的所有小写字母
print(re.findall("[a-z]+", msg)) # ['ello', 'the', 'count', 'of', 'today', 'is']
# 匹配字符串中的所有大写字母
print(re.findall("[A-Z]+", msg)) # ['H']
# 匹配字符串中的所有字母
print(re.findall("[A-Za-z]+", msg)) # ['Hello', 'the', 'count', 'of', 'today', 'is']
(六)正则表达式分组
正则表达式是用于进行字符串检索匹配操作的利器,在一次完整的匹配过程中,可以将匹配结果进行分组,这样更加细化了咱们对匹配结果的操作,正则表达式通过圆括号()进行分组,以便提取匹配结果的部分结果。
常见分组:
分组 | 描述 |
分组 | 描述 |
(expression) | 使用圆括号直接分组; 正则表达式本身匹配结果就是一个组,可以通过group()或者group(0)获取; 然后正则表达式中包含的圆括号就是按照顺序从1开始编号 |
(?P< name>expression) | 使用圆括号分组,然后给当前圆括号表示的小组命名为name,可以通过group(name)进行数据的获取 |
import re
# 座机号码格式“010-6688465”
phone = input("请输入座机号码:") # 请输入座机号码:010-22334455
# 进行正则匹配
real = re.search(r"^(\d{3,4})-(\d{4,8})", phone)
# search和match匹配得到的结果是match对象
print(real) # <re.Match object; span=(0, 12), match='010-22334455'>
# 通过group()获取结果
print(real.group()) # 010-22334455
# 获取结果中第一个括号对应的组数据:区号
print(real.group(1)) # 010
# 获取结果中第二个括号对应的组数据:号码
print(real.group(2)) # 22334455
# 进行正则匹配,使用第二种方法进行分组
res2 = re.search(r"(?P<start>\d{3,4})-(?P<end>\d{4,8})$", phone)
# 查看匹配结果
print(res2) # <re.Match object; span=(0, 12), match='010-22334455'>
# 通过组名获取分组信息
print(res2.group(0)) # 010-22334455
print(res2.group("start")) # 010
print(res2.group("end")) # 22334455
(七)贪婪模式和懒惰模式
贪婪模式:从目标字符串的两头开始搜索,一次尽可能多的匹配符合条件的字符串,但是有可能会匹配到不需要的内容,正则表达式中的元字符、量词、范围等都是贪婪匹配模式,使用的时候一定要注意分析结果。避免获取到了多余的内容。
如:
.
就是一个贪婪模式,用于匹配
和
之间所有的字符
懒惰模式:从目标字符串按照顺序从头到尾进行检索匹配,尽可能的检索最小范围的匹配结果,语法结构是在贪婪模式的表达式后面加上一个?号即可。
如:
.?
就是一个 懒惰模式的正则,用于仅仅匹配最小范围的
和
之间的内容
import re
new_string = "hello world. hello my friend"
# 贪婪模式匹配查找以h开头,以o结尾的单词
res = re.findall("h.*o", new_string)
print(res) # ['hello world. hello'] 出现了多余的内容
# 懒惰模式匹配查找以h开头,以o结尾的单词
res = re.findall("h.*?o", new_string)
print(res) # ['hello', 'hello'] 符合期望查找内容
结尾
正则表达式在爬虫项目中使用较多,因此掌握正则表达式非常重要,本文中还没有将正则表达式的所有操作都整理出来,而是整理了部分比较常用的知识点。与我而言,目前这些操作暂时够用了,以后遇到更多的正则表达式操作的时候再进行整理吧。谢谢大家的观看啦,拜了个拜~~