开篇絮絮念

最近接触到了正则表达式这一概念,但是还不熟悉,借此整理所学知识并且分享给大家,大家看到有兴趣的话欢迎留言评论哦。

正则表达式概念

正则表达式:也称规则表达式(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'] 符合期望查找内容

结尾

正则表达式在爬虫项目中使用较多,因此掌握正则表达式非常重要,本文中还没有将正则表达式的所有操作都整理出来,而是整理了部分比较常用的知识点。与我而言,目前这些操作暂时够用了,以后遇到更多的正则表达式操作的时候再进行整理吧。谢谢大家的观看啦,拜了个拜~~