正则表达式入门

正则表达式入门

Chen

2025-02-16 发布16 浏览 · 0 点赞 · 0 收藏

第一章 正则表达式简介

本教程基于b站up主:苑昊老师
教程链接:一节课精通正则表达式与re模块_哔哩哔哩_bilibili

一、基本介绍

正则表达式:Regular Expression

作用:处理复杂文本信息

灵魂:模糊查询

第二章 二元字符之通配符和字符集

一、元字符

​ 元字符是具有特殊含义的字符。常用的11个元字符就是正则的灵魂。

二、通配符:.

通配符的作用:能匹配**==一个==**除了\n以外的任意符号

1、.:匹配一个处理\n以外的任何符号

import re

s = "apple appe a1e a2e amaze a\ne"
# 找a和e中间隔了一个字符的字符串
res = re.findall(pattern="a.e", string=s)
print(res) 

输出结果:

['a1e', 'a2e', 'aze']

s = "apple appe a1e a2e amaze a\ne"
# 找a和e中间隔了两个字符的字符串
res2 = re.findall(pattern="a..e",string=s)
print(res2)

输出结果

['appe']

2、re.S模式:能够匹配\n

s1 = "aabcce abcde a\ne ace a2e"
# 设置通配符能匹配\n
res3 = re.findall("a.e",s1,re.S)
print('res3',res3)

es3 ['a\ne', 'ace', 'a2e']

三、字符集:[]

作用:匹配**==一个==**[]中的字符,[]中没有的字符不能匹配

1、应用举例

import re
s = ["alpe","ale", "ape", "a2e", "a!e", "a_e", "aae", "a\e", "ae", "a\re"]
res1 = re.findall("a.e", str(s))
print("res1=",res1)
res2 = re.findall("a[0-9a-z]e", str(s))
print("res2=",res2)
res3 = re.findall("a[lp]e", str(s))
print("res3=",res3)

运行结果:

res1= ['ale', 'ape', 'a2e', 'a!e', 'a_e', 'aae']
res2= ['ale', 'ape', 'a2e', 'aae']
res3= ['ale', 'ape']

  • 如果要表示a到z:a-z
  • A到Z:A-Z
  • 0-9:0-9

3、应用举例:取反^

s = ["alpe","ale", "ape", "a2e", "a!e", "a_e", "aae", "a\e", "ae", "a\re"]
# 只要不是数字就提取
res4 = re.findall("a[^0-9]e", str(s))
print("res4=",res4)

输出结果:

res4= ['ale', 'ape', 'a!e', 'a_e', 'aae']

s = ["alpe","ale", "ape", "a2e", "a!e", "a_e", "aae", "a\e", "ae", "a\re"]
# 只要不是数字或者小写字母就提取
res5 = re.findall("a[^0-9a-z]e",str(s))
print("res5=",res5)

res5= ['a!e', 'a_e']

第三章 重复元字符:{}、*、+、?

一、数量范围贪婪符{}:指定左边原子符重复的次数

假如我们要匹配:a中间三个字符e,就要写a...e,假如有一百个字符呢?不可能写一百个.吧,这个时候{}的作用就体现出来了1、

1、指定重复元素次数

s = 'abbbc abbc abc'
# 匹配ab{2,3}c
res7 = re.findall('ab{2,3}c',s)
print("res7=",res7)

res7= ['abbbc', 'abbc']

import re
s = ["aabce","aaqce", "aape", "a2e", "a!e", "a_e", "aae", "a\e", "ae", "a\re"]
# 匹配符合:a中间三个字符e,规则的字符串
res1 = re.findall("a.{3}e", str(s))
print("res1=",res1)

res1= ['aabce', 'aaqce']

2、指定重复元素次数范围

s = ["aabce","aaqce", "aape", "a2e", "a!e", "a_e", "aae", "a\e", "ae", "a\re"]
res2 = re.findall("a.{2,3}e", str(s))
print("res2=",res2)

3、默认贪婪匹配

s1 = "aeeee"
res3 = re.findall("a.{1,3}e",s1)
print("res3=",res3)

res3= ['aeeee']

贪婪匹配:如果字符串符合多种情况,默认按能匹配的最长的匹配

4、{}?:取消重复符的贪婪匹配

贪婪匹配:如果字符串符合多种情况,默认按能匹配的最短的匹配

s1 = "aeeee"
# 选择非贪婪匹配
res4 = re.findall("a.{1,3}?e",s1)
print("res4=",res4)

res4= ['aee']

5、设置重复次数可以为无穷大

s1 = "aabcce abcde abce ace a2e"
# 重复范围:2到无穷
res5 = re.findall("a.{2,}e",s1)
print("res5=",res5)

res5= ['aabcce abcde abce ace a2e']

因为可以是无穷大且没有取消贪婪模式,所以实际上匹配的字符串是这一整个(只有一个匹配结果)

6、结合[]进行匹配

s = ["aabce","aaqce", "aape", "a2e", "a!e", "a_e", "aae", "a\e", "ae", "a\re"]
# 只匹配字母,不匹配其他字符
res6 = re.findall('a[a-z]{2,3}e',str(s))
print("res6=",res6)

res6= ['aabce', 'aaqce', 'aape']

二、*:等同于{0,}

==默认贪婪==

左边的原子符号可以出现0次或无穷次

1、应用举例:爬页面热搜新闻

细节.*?:取消贪婪匹配

三、+:等同于{1,}

==默认贪婪==

左边的原子符号可以出现1次至无穷次

1、应用案例:爬取信息是防止空的信息被爬取

四、?:等同于{0,1}

==默认贪婪==

左边的原子符号可以出现0次或1次

应用案例

这么写的话没法把http开头的网址提取出来

这样就可以了

??:取消贪婪匹配

第四章 元字符之^和$

一、开始边界符^:必须以符合规则的字符串开头

像这个path就是以不符合规则的字符串开头,所以就匹配不到

二、结束边界符$:必须以符合规则的字符串结尾

像这个path就是以不符合规则的字符串结尾的,所以也匹配不到

三、代码

import re
s = 'https://www.baidu.com/123'
res = re.findall('www.[a-z]*.com',s)
print('res=',res)

# 如果要必须以www.开头才能匹配
res1 = re.findall('^www.[a-z]*.com',s)
print('res1=',res1)


# 如果要必须以www.开头才能匹配
res4 = re.findall('^https://www.[a-z]*.com',s)
print('res4=',res4)

# 必须要以.com结尾才能匹配到
res2 = re.findall('www.[a-z]*.com$',s)
print('res2=',res2)

# 必须要以.com/123结尾才能匹配到
res3 = re.findall('www.[a-z]*.com/123$',s)
print('res3=',res3)

res= ['www.baidu.com']
res1= []
res4= ['https://www.baidu.com']
res2= []
res3= ['www.baidu.com/123']

第五章 转义符 \

一、转义符的两个功能

1、赋予某些普通符号特殊功能

二、将特殊符号普通化

1、\\d:防止python解释器报警告

告诉python解释器\d是普通的re模块里的\d,不是python里的\d

import re
s = 'zhangsan 123 lisi 23 wangwu 9387'
res = re.findall( '\\d+',s)
print('res=',res)

res= ['123', '23', '9387']

也可以通过在规则前加r,表明这种写法是原生的

import re
s = 'zhangsan 123 lisi 23 wangwu 9387'
res = re.findall( r'\d+',s)
print('res=',res)

res= ['123', '23', '9387']

2、用\防止.被识别为通配符

s = 'wwwxbaiduxcom www.baidu.com'
res1 = re.findall('www.[a-z]*.com',s)
print('res=',res1)

res= ['wwwxbaiduxcom', 'www.baidu.com']

我们想识别的是www.和.com,但是这里的.被当做通配符了,所以要通过\来使其普通化

s = 'wwwxbaidu.com www.baidu.com'
res = re.findall(r'www\.[a-z]*.com',s)
print('res=',res)

res= ['www.baidu.com']

3、\*:提取字符串中的*,防止被识别成重复元字符

s = '*** ******* *****'
res = re.findall(r'\*+',s)
print('res=',res)

4、提取路径

s = r'\user\now\1.png,\user\now\b.png,\user\now\apple.png,\user\n.png'
# 提取\user\now文件夹下的png文件
res = re.findall(r'\\user\\now\\.+png',s)
print('res=',res)

res= ['\user\now\1.png,\user\now\b.png,\user\now\apple.png,\user\n.png']

这里是进行贪婪匹配了,直接选择了最长的符合\user\now开头png结尾的字符串!!!woc我都没意识到

需要通过?取消.+的贪婪匹配

s = r'\user\now\1.png,\user\now\b.png,\user\now\apple.png,\user\n.png'
# 使用非贪婪匹配,并且明确限定路径分隔符
res = re.findall(r'\\user\\now\\.+?\.png', s)
print('res=', res)

res= ['\user\now\1.png', '\user\now\b.png', '\user\now\apple.png']

三、\d:等价于[0-9]

import re
s = 'zhangsan 123 lisi 23 wangwu 9387'
reg = '\d+'
res = re.findall(reg,s)
print('res=',res)

res= ['123', '23', '9387']

四、\b:匹配单词边界

# \b用法
s1 = 'cat1 catyou cat! i love cat'
res1 = re.findall(r'cat\b',s1)
print('res1=',res1)

res1= ['cat', 'cat']

因为这两个cat后是单词边界,所以能被匹配出来

单词边界:只要后面跟的不是字母或者数字就说明是单词边界

第六章 元字符之()与|

一、()分组与优先提取

1、优先提取:提取@qq.com前的内容

import re
s = 'admin@qq.com sierxing@123qq.com zsw@qq.com 123@qq.com'
res = re.findall(r'\w+@qq.com',s)
print('res=',res)
res1 = re.findall(r'(\w+)@qq.com',s)
print('res1=',res1)

res= ['admin@qq.com', 'zsw@qq.com', '123@qq.com']
res1= ['admin', 'zsw', '123']

2、优先提取:爬虫提取标签内的内容

优先提取:提取括号内的内容

3、提取连续的字符串

s = 'appleappleapple appleapple apple'
# 提取连续的两个或三个apple
res = re.findall(r'(?:apple){2,3}',s)
print('res=',res)

res= ['appleappleapple', 'appleapple']

需要通过?:取消优先提取,不然在匹配到appleappleapple和appleapple后,只会提取第一个apple

s = 'appleappleapple appleapple apple'
# 提取连续的两个或三个apple
res = re.findall(r'(apple){2,3}',s)
print('res=',res)

res= ['apple', 'apple']

二、|:或

1、查找有没有apple或banana或orange

import re
s = "i love apple,banana,orange"
res = re.findall('apple|banana|orange',s)
print('res=',res)

res= ['apple', 'banana', 'orange']

如果用字符集的形式就是错的

import re
s = "i love apple,banana,orange"
res = re.findall('[apple|banana|orange]',s)
print('res=',res)

res= ['l', 'o', 'e', 'a', 'p', 'p', 'l', 'e', 'b', 'a', 'n', 'a', 'n', 'a', 'o', 'r', 'a', 'n', 'g', 'e']

import re
s = "i love apple,banana,orange"
res = re.findall('[applebananaorange]',s)
print('res=',res)

res= ['l', 'o', 'e', 'a', 'p', 'p', 'l', 'e', 'b', 'a', 'n', 'a', 'n', 'a', 'o', 'r', 'a', 'n', 'g', 'e']

2、同时匹配.com和.cn结尾的域名

# 同时匹配.com和.cn结尾的域名
s1='www.baidu.com www.sina.cn www.google.com'
res1 = re.findall('www\.\w+\.com|www\.\w+\.cn',s1)
print('res1=',res1)

res1= ['www.baidu.com', 'www.sina.cn', 'www.google.com']

3、(?:):取消优先提取

# 同时匹配.com和.cn结尾的域名
s1='www.baidu.com www.sina.cn www.google.com'
res1 = re.findall('www\.\w+\.(?:com|cn)',s1)
print('res1=',res1)

res1= ['www.baidu.com', 'www.sina.cn', 'www.google.com']

如何只提取出域名部分,在需要提取的部分添加()

# 同时匹配.com和.cn结尾的域名
s1='www.baidu.com www.sina.cn www.google.com'
res1 = re.findall('www\.(\w+)\.(?:com|cn)',s1)
print('res1=',res1)

res1= ['baidu', 'sina', 'google']

第六章 re模块中的常用函数

重点学习的函数:

  • findall
  • search
  • complie

一、findall

二、search

参数跟findall一样,但找的是第一个符合规则项

1、找到一个ERROR

查看返回的match对象信息

2、有名提取

search函数不能使用()优先提取,但如果我们想要提取search匹配结果的某一部分,就需要给那一部分取个名字

同样用()包起来想要提取的部分,在开头协商?P<名字>

如果不使用名字提取的话就会提取整体

三、match

跟search语法一样,唯一的区别是在匹配规则相同时,match相当于在search的匹配规则前加了一个^,即只会看文本的开头是不是符合规则的字符串,是就返回,不是就返回None

四、split

五、sub和subn

六、complie

用前面的函数,每对一段文本匹配一次,就要编译一次匹配规则,如果对一百段文本匹配,就要编译一百次匹配规则,

用complie的话就只会编译一次匹配规则(一开始就把规则放到complie对象里面),然后用这个规则对一百段文本进行匹配,可以极大的提高性能

1、用complie对象对多个文本进行匹配

请前往 登录/注册 即可发表您的看法…