首页 > 编程语言 >Python爬虫知识体系-----正则表达式-----持续更新

Python爬虫知识体系-----正则表达式-----持续更新

时间:2024-11-13 17:15:14浏览次数:3  
标签:匹配 Python pattern 爬虫 字符串 ----- matcher print group

数据科学、数据分析、人工智能必备知识汇总-----Python爬虫-----持续更新:https://blog.csdn.net/grd_java/article/details/140574349

文章目录

一、正则基础

1. 为什么使用正则

正则可以让我们方便的做字符串匹配,检验字符串格式,检索指定内容(子串)


  1. 例如,判断一个字符串是否是手机号等等
  2. 例如,提取文本中的所有ip地址

2. 正则与re模块简介

正则表达式,又称规则表达式


  1. 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern)
  2. 正则匹配是一个 模糊的匹配(不是精确匹配)

re模块


  1. python自1.5版本开始增加了re模块,该模块提供了perl风格的正则表达式模式
  2. 常用方法如下
  1. match()
  2. search()
  3. findall()
  4. finditer()

二、正则表达式

1. 匹配单个字符与数字

匹配说明
.匹配除换行符以外的任意字符,当flags被设置为re.S时,可以匹配包含换行符在内的所有字符
[]里面是字符集合,匹配[里任意一个字符
[0123456789]匹配任意一个数字字符
[0-9]匹配任意一个数字字符
[a-z]匹配任意一个小写英文字母字符
[A-Z]匹配任意一个大写英文字母字符
[A-Za-z]匹配任意一个英文字母字符
[A-Za-z0-9]匹配任意一个数字或英文字母字符
[^lucky][]里的^称为脱字符,表示非,匹配不在内的任意一个字符
^[lucky]以[]中内的某一个字符作为开头
\d匹配任意一个数字字符,相当于[0-9]
\D匹配任意一个非数字字符,相当于[^0-9]
\w匹配字母、下划线、数字中的任意一个字符,相当于[0-9A-Za-z_]
\W匹配非字母、下划线、数字中的任意一个字符,相当于[^0-9A-za-z_]
\s匹配空白符(空格、换页、换行、回车、制表),相当于[ \f\n\r\t];注意[]里面有空格哦
\S匹配非空白符(空格、换页、换行、回车、制表),相当于[^ \f\n\r\t];注意[]里面有空格哦

2. 限定符

符号描述示例示例解析
{num}按指定规则一次性匹配num个字符\d{3}按照\d规则,匹配连续的3个字符,这3个字符全部满足\d规则
?按照指定规则,匹配0或1个字符\d?按照\d规则,匹配0或1个字符
*相当于{0,}。按照指定规则,匹配任意个字符(0个,1个或多个)\d*按照\d规则匹配任意个
+相当于{1,}。按照指定规则,匹配1个或多个字符\W+按照\W规则,匹配非数字或字母字符,1个或多个

默认贪婪匹配,例如+代表匹配1个或多个,如果当前字符串符合条件的连续字符有多个,默认贪婪匹配多个,而不是1个1个匹配。

如何取消贪婪匹配,选择用非贪婪匹配呢?只需要限定符后面加个?即可。例如我们想要从java0123完成匹配

  1. java\\d*表示java开头,后面跟随0或多个数字。会直接匹配出java0123,因为是贪心匹配,优先尽可能多的匹配
    在这里插入图片描述

python代码如下:看到了吗,python更方便,而java更特殊,几乎只有java的正则表达式是需要两个\的,python只需要一个
在这里插入图片描述

  1. java\\d*?表示java开头,后面跟随0或多个数字,并且非贪婪匹配。则会匹配出java,因为是非贪婪匹配,优先尽可能少的匹配,而*表示匹配0或多个,最少就是0个,所以非贪婪优先最少,也就是0个
    在这里插入图片描述

python代码
在这里插入图片描述

{num}:按照指定规则,连续num个字符匹配。就是至少连续num个符合指定规则的字符才能完成匹配

使用例子"123abc1234abc123456789",我们要对其中123,1234,123456789进行匹配

  1. 直接用{num}形式,表示必须num个,不能多也不能少。下面例子中,我们按照1[0-9]规则并限定[0-9]{2}.也就是1开头,后面跟[0-9]数字,必须长度为2,不能多也不能少。

下图结果中可以看出,1开头满足后,只会匹配2个[0-9]的数字,多一个少一个都没有匹配到
在这里插入图片描述


python代码
在这里插入图片描述

  1. 用{num,}形式,表示至少匹配num个,上不封顶,我们[0-9]{num,}进行匹配时,会匹配[0-9]至少两个,多了也没关系,但是不能少

下图结果中可以看出,1开头满足后,后面匹配[0-9]至少2个,但是上不封顶
在这里插入图片描述


python
在这里插入图片描述

  1. 用{left,right}形式,至少匹配left个,最多匹配right个。默认贪婪匹配,如果一次性匹配不完(原字符串符合规则字符个数超出right,优先先匹配right个,剩下的再依次匹配)

下图中,我们限定开头必须是1,且对[0-9]限定至少2个,最多4个。匹配结果也同样满足条件
在这里插入图片描述


python
在这里插入图片描述

3. 定位符

规定要匹配的字符串出现的位置,比如在字符串开始还是结束位置。换句话说:指定要匹配的位置

符号描述示例示例解析
^指定起始字符^[0-9]+[a-z]*至少1个数字开头,后接任意个小写字母
$指定结束字符^[0-9]\-[a-z]+$以一个数字开头,接连字符"-",至少1个小写字母结尾
\b匹配以指定规则结尾的边界yin\b*边界:用空格分开的子串的两边,或目标字符串的起始和结束位置,例如这个字符串“yinabcdyin aaaayin”,标黄的位置就是以yin结尾的边界
\B\b的含义正好相反,匹配以指定规则开头的边界yin\Byinabcdyin aaaayin”,其中标黄的是以yin为开头的边界
\A匹配字符串的开始,和^的区别是\A只匹配整个字符串的开头即使在re.M模式下也不会匹配每行的行尾
\Z匹配字符串的结尾,只匹配整个字符串的结尾

4. 选择匹配符

一个竖杠|就是选择匹配符,和或运算符||有异曲同工之妙.表示只要满足一个条件就匹配

例如我们想要实现匹配Java或者抓哇。两个随便一个都行,就可以通过选择匹配符来实现。下面的例子中,想要在字符串java抓哇中,匹配出java或者抓哇。那么就可以使用正则表达式java|抓哇
在这里插入图片描述


python
在这里插入图片描述

5. ()小括号的作用

  1. 和我们做数学题一样,起到一个"先算括号里面的东西"的作用
  2. 被小括号括起来的东西,会作为一个子存储被存储起来。和java底层实现差不多,可以参考一下:https://blog.csdn.net/grd_java/article/details/136120841

那么作为子存储匹配到的值,存储后,如何取出来呢?可以通过re模块常用函数group()进行

请参考下面《re模块中常用函数》中的《search函数》

三、re模块中常用函数

1. 通用flags(修正符)

说明
re.I匹配时对大小写不敏感
re.M多行匹配,影响到^和$
re.S.匹配包括换行符在内的所有字符

如果要多个条件同时使用,通过|来拼接
在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = 'alksdjflksjal====192.168.0.1==186.725.111.565==kfjlkasjflkjdsladf'
pattern = ("(?P<one>[0-9]{1,3})."
           "(?P<two>[0-9]{1,3})."
           "(?P<three>[0-9]{1,3})."
           "(?P<four>[0-9]{1,3})")
print(pattern)
matcher = re.findall(pattern, string,re.I|re.S|re.M)

print("matcher:",matcher)

2. 通用函数

获取匹配结果

使用group()方法获取匹配到的值


groups()返回一个包含所有小组字符串的元组(也就是自存储的值),从1到 所含的小组号

3. match函数

从头匹配,只匹配一次。相当于search(“^”,string)

def match(pattern, string, flags=0):
'''
	pattern:	匹配的正则表达式(一种字符串的模式)
	string:		要匹配的字符串
	flags:		标识位,用于控制正则表达式的匹配方式
'''

从字符串第一位开始匹配,匹配成功返回匹配到的match对象。失败返回None。只匹配一次,就算字符串中有多个满足pattern条件的子串,也只返回第一个满足pattern的匹配

可以理解为它只匹配字符串以什么开头。所以人如其名,这个函数主要用于匹配,检查。例如是否满足我们要求的秘密格式。

例如有一个字符串x123456,此时我们匹配[a-z],那么会匹配出x。因为字符串中第一个字符确实是x
在这里插入图片描述


但是如果字符串是1x23456,此时我们匹配[a-z],就会返回None。因为字符串第一个字符压根不是字母
在这里插入图片描述

4. search函数

子串搜索,只匹配一次

def search(pattern, string, flags=0):
'''
	pattern:	匹配的正则表达式(一种字符串的模式)
	string:		要匹配的字符串
	flags:		标识位,用于控制正则表达式的匹配方式
'''

扫描整个字符串string,并返回第一个pattern模式成功的匹配,失败就返回None

只要字符串包含就可以,只匹配一次。和match要区分开,虽然他俩都只匹配一次。但是match必须从字符串第一个字符开始匹配,要是有一个对不上就失败。但search只要子串中匹配到就算成功。


也就是说,如果整个字符串有两个符合条件的子串,只会返回最先遇到的,匹配成功后,后面的字符串甚至直接省略不看了。

4.1 捕获分组

  1. (pattern):用一对小括号来实现分组称为非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其它捕获结果则根据左括号的顺序从1开始自动编号。

pattern是匹配规则,也就是要分组的正则表达式

  1. (?P< name>pattern):命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符合,并且不能以数字开头。

匹配字符串中的ip地址,并且为每一段地址分组,让我们可以方便的将每一段截取出来。因为search函数只匹配一次,所以字符串就算有多个ip地址,也只会匹配第一次遇到的
在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = 'alksdjflksjal====192.168.0.1==186.725.111.565==kfjlkasjflkjdsladf'
pattern = ("(?P<one>[0-9]{1,3})." +
                "(?P<two>[0-9]{1,3})." +
                "(?P<three>[0-9]{1,3})." +
                "(?P<four>[0-9]{1,3})")
matcher = re.search(pattern, string)

print("matcher:",matcher)
print("matcher.group():",matcher.group())
print("matcher.groups():",matcher.groups())
print("matcher.group('one'):",matcher.group('one'))
print("matcher.group('two'):",matcher.group('two'))
print("matcher.group('three'):",matcher.group('three'))
print("matcher.group('four'):",matcher.group('four'))

不起名字的话,就只能用数字来获取指定个分组,例如第一个分组。

注意group(0),也就是第0组,就是整个匹配的串
在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = 'alksdjflksjal====192.168.0.1==186.725.111.565==kfjlkasjflkjdsladf'
pattern = ("([0-9]{1,3})." +
                "([0-9]{1,3})." +
                "([0-9]{1,3})." +
                "([0-9]{1,3})")
matcher = re.search(pattern, string)

print("matcher:",matcher)
print("matcher.group():",matcher.group())
print("matcher.groups():",matcher.groups())
print("matcher.group(1):",matcher.group(1))
print("matcher.group(2):",matcher.group(2))
print("matcher.group(3):",matcher.group(3))
print("matcher.group(4):",matcher.group(4))

5. findall()函数(返回列表)

def findall(pattern, string, flags=0):
'''
	pattern:	匹配的正则表达式(一种字符串的模式)
	string:		要匹配的字符串
	flags:		标识位,用于控制正则表达式的匹配方式
'''

扫描整个字符串string,返回所有匹配的pattern模式结果字符串列表

前面两个方法是找一次(找第一个匹配),这个是找多个,但是它会将所有匹配结果直接通过列表返回,而不是单独的match对象

6. finditer()函数(返回match对象迭代器)

finditer也是找多个,但是会返回一个迭代对象,每个匹配都会作为一个match对象返回

def finditer(pattern, string, flags=0):
'''
	pattern:	匹配的正则表达式(一种字符串的模式)
	string:		要匹配的字符串
	flags:		标识位,用于控制正则表达式的匹配方式
'''

在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = 'alksdjflksjal====192.168.0.1==186.725.111.565==kfjlkasjflkjdsladf'
pattern = ("(?P<one>[0-9]{1,3})."
           "(?P<two>[0-9]{1,3})."
           "(?P<three>[0-9]{1,3})."
           "(?P<four>[0-9]{1,3})")
print(pattern)
matcher = re.finditer(pattern, string)

print("matcher:",matcher)
for match in matcher:
    print("================================================")
    print(match)
    print("match.group():",match.group())
    print("match.groups():",match.groups())
    print("match.group('one'):",match.group('one'))
    print("match.group('two'):",match.group('two'))
    print("match.group('three'):",match.group('three'))
    print("match.group('four'):",match.group('four'))
    print("================================================")

当然了,既然是迭代器,用next()函数也是可以的

next函数源码解释

def next(iterator, default=None): # real signature unknown; restored from __doc__
    """
    next(iterator[, default])
    返回迭代器中下一个条目
    Return the next item from the iterator. If default is given and the iterator
    is exhausted, it is returned instead of raising StopIteration.
    """
    pass

则代码可以变成
在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = 'alksdjflksjal====192.168.0.1==186.725.111.565==kfjlkasjflkjdsladf'
pattern = ("(?P<one>[0-9]{1,3})."
           "(?P<two>[0-9]{1,3})."
           "(?P<three>[0-9]{1,3})."
           "(?P<four>[0-9]{1,3})")
print(pattern)
matcher = re.finditer(pattern, string)
print("matcher:",matcher)
match1 = next(matcher)
print("match1:",match1)
match2 = next(matcher)
print("match2:",match2)

7. split()函数

切割字符串

def split(pattern, string, maxsplit=0, flags=0):
'''
	pattern:	匹配的分隔符(依据什么进行分隔)
	string:		要分割的字符串
	maxsplit:	如果非0,则最多分隔出maxsplit个,剩下的会作为list中最后一个元素进行返回
	flags:		标识位,用于控制正则表达式的匹配方式
'''

maxsplit指定为1,则会按指定分隔符分割一个元素出来,剩下的作为list最后一个元素返回
在这里插入图片描述

如果maxspit为默认值0,则会完全分割
在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = '010203,121314,222324;686967'
pattern = (",|;")
matcher = re.split(pattern=pattern,string=string,maxsplit=0,flags=0)
print("matcher:",matcher)

8. 编译

当在python中使用正则表达式时,re模块会做两件事,一件是编译正则表达式,如果表达式的字符串不合法,会报错。另一件是用编译好的正则表达式提取匹配字符串

如果一个正则表达式要使用几千遍,每一次都会编译,出于效率的考虑进行正则表达式的编译,就不需要每次使用都编译了,节省了编译的时间,从而提升效率

def compile(pattern, flags=0):

将pattern模式编译成正则对象

在这里插入图片描述

'''导包(start)'''
import re
'''导包(end)'''
string = '010203,121314,222324;686967'
pattern = (",|;")
compile = re.compile(pattern=pattern, flags=re.S)
print(type(compile))
# 保存为正则对象后,就可以用它调用匹配函数,进行使用了
print(compile.split(string))

标签:匹配,Python,pattern,爬虫,字符串,-----,matcher,print,group
From: https://blog.csdn.net/grd_java/article/details/143730215

相关文章

  • 面试合集1-sql篇
     学生表s 成绩表grade1.查询所有学生的数学成绩,显示学生姓名name,分数,由高到低2、统计每个学生的总成绩,显示字段:姓名,总成绩 3、统计每个学生的总成绩(由于学生可能有重复名字),显示字段:学生id,姓名,总成绩 4、列出各门课程成绩最好的学生,要求显示字段:学号,姓名,科......
  • python实现赛博宠物(纯代码无需素材)
    1、创作背景    今天如往常一样来上班,一进公司就看见财务小姐姐闷闷不乐,就走过去跟她聊天,她说她很想养一只小狗,但是家里面不同意,怕把家里弄得乱七八糟。看着小姐姐悲伤的样子,我恏大力最舍不得小姐姐不开熏,所以我恏大力就要出来帮助美丽的财务小姐姐咯。2、技术选择......
  • 忽悠财务小姐姐神器(python实现3D爱心)
    1、设计背景        最近在网上看到了很多粒子爱心的python源码,所以就突发奇想也做一个爱心,但是粒子爱心这么多人做了就没什么意思了,那我就来做一个3D粉嫩旋转爱心,要的就是别出心裁,出人意料。这发给财务小姐姐,我恏大力的春天不就来了!!2、使用技术        这......
  • 通过爬虫方式获取小红书授权登录的cookie的代码
    1、代码里的normal_sign.js代码是某书签名算法xs,xt的实现-CSDN博客里的;2、CookieUtil工具代码见抖音最新bd-ticket-guard-client-data逆向方法(2024年11月)-CSDN博客里的CookieUtil.py;importjsonimporttimeimportzlibfromurllib.parseimporturlparseimportexecj......
  • BRICS2024-ST-010-2024一带一路暨金砖国家技能发展与技术创新大赛之企业信息系统安全
    未来技能·创造未来2024一带一路暨金砖国家技能发展与技术创新大赛【企业信息系统安全赛项】BRICS2024-ST-010决赛技术规程金砖国家工商理事会(中方)技能发展工作组一带一路暨金砖国家技能发展与技术创新大赛组会竞赛技术委员会专家组制定2024年4月未来技能·创造未......
  • BRICS2024-ST-010-2024一带一路暨金砖大赛之-企业信息系统安全赛项(选拔赛)技术规程
    未来技能·创造未来2024一带一路暨金砖国家技能发展与技术创新大赛【第二届企业信息系统安全赛项】BRICS2024-ST-010技术规程(选拔赛)金砖国家工商理事会(中方)技能发展工作组一带一路暨金砖国家技能发展与技术创新大赛组会竞赛技术委员会专家组制定2024年4月未来技能......
  • NOIP 模拟赛:2024-11-11
    T1:法一:\(O(n^2)\)的DP。\(dp[i][j][0/1]\)表示在\(i\)的子树内染色,\(i\)是红/黑,使得每个要求的结点的黑点个数都等于\(j\)。法二:\(O(n)\)的神秘做法。取出最浅的被要求结点,把深度\(\le\)它的都染成黑色,其余点都染成红色。T2:对于一个元素属于\([0,2^m)\),且互不相......
  • Java方法-方法的定义和调用
    方法的定义和调用方法的定义Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:方法包含一个方法头和一个方法体。下面是一个方法的所有组成部分:修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型......
  • GIS融合之路(八)-如何用Cesium直接加载OSGB文件(不用转换成3dtiles)
    系列传送门:山海鲸可视化:GIS融合之路(一)技术选型CesiumJS/loaders.gl/iTowns?山海鲸可视化:GIS融合之路(二)CesiumJS和ThreeJS深度缓冲区整合山海鲸可视化:GIS融合之路(三)CesiumJS和ThreeJS相机同步山海鲸可视化:GIS融合之路(四)如何用CesiumJS做出CesiumForUnreal的效果山海鲸可视化......
  • 开源低代码平台-Microi吾码-工作流引擎、流程引擎
    前言第一版:博主在2008年工作时接手前同事基于微软WWF开发的工作流引擎,开发十余个国企、事业单位OA系统、ERP系统等第二版:博主在2012年参与ccflow工作流引擎的二次开发、bug修复,曾是ccflow论坛超级版主,当时使用微软SelverLight技术(可惜被淘汰)。ccflow的老板周总也是咱前辈......