文章目录

  • 页面解析和数据提取
  • 什么是正则表达式
  • 四大奇术:
  • 正则常用的元字符列表:
  • 原子的案例代码:
  • 元字符:[原子修饰符]
  • 与数量相关的元字符的使用
    • 1、+的使用:
    • 2、?的使用:
    • 3、/*(星号)的使用
    • 对中括号[]的详解:
    • 对.和\*和[]的进一步认识
    • 4、{m}的使用,表示必须是m个修饰的原子
    • 5、{m,n}的使用:
    • 6、{m,}的使用:
    • 7、{,n}的使用
    • \A的使用:
    • \Z的使用:
    • 多行模式
    • ^的使用:
    • $的使用:
    • \b的使用:
    • \B的使用:
    • |竖线的使用:
    • ()小括号的使用:
  • 模式修正符:
    • re.A的使用:
    • re.U的使用:
    • re.S的使用:
    • re.m的使用:
    • re.x的使用:
    • re.I的使用:
  • 转义字符的应用:
  • 扩展正则语法:
    • 1、(?Limsuxa)这是模式修正符的第二种应用方法
    • 2、(?:)的使用:取消单元存储功能
    • 3、(?P\):的使用
    • 4、(?P=name):
    • 5、(?#):
    • 6、(?=):正向先行断言 (零宽断言)
    • 7、(?!):负向先行断言(零宽断言)
    • 8、(?<=):正向后行断言(零宽断言)
    • 9、(?<!):负向后行断言(零宽断言)
    • 10、零宽断言先行和后行注意事项
    • 11、零宽断言的后行注意事项
    • 12、(?(id/name)Y|N):
  • 正则表达式的实例书写
    • 1、qq邮箱的设定
    • 2、IP地址的设定
    • 3、电话号码的匹配
    • 4、身份证号码的匹配
    • re模块:正则表达式专用模块,提供正则相关的操作方法
    • 正则表达式匹配过程图
    • 1、compile()方法:
    • 2、escape()对字符串进行转义处理
    • 3、findall()正则表达式方法:
    • 4、finditer()正则表达式方法:
    • 5、match()方法正则表达式方法:
    • 6、search()正则表达式方法
    • 7、split切割字符串方法
    • 8、sub方法:正则的替换
    • 9、subn()方法正则替换
  • 第二种,正则对象的方法(协助compile方法获取)
    • 1、findall()正则表达式对象方法:
    • 2、finditer()正则表达式对象方法:
    • 3、matc()h正则表达式对象方法:
    • 4、search()正则表达式对象方法:
    • 5、spilt()正则表达式对象方法:
    • 6、sub()正则表达式方法:正则替换字符串
    • 7、subn正则表达式对象方法:
  • 正则表达式对象方法提供的几个属性:
    • 1、flags()属性:
    • 2、pattern()属性:
    • 3、groups属性:
    • 4、groupindex属性:
  • group,span,start,end属性:
    • 1、match()正则表达式方法group,span,start,end属性的使用
    • 2、match()正则表达式对象方法group,span,start,end属性的使用
    • 3、search方法: 正则表达式方法group,span,start,end属性的使用
    • 4、search方法正则表达式对象方法group,span,start,end属性的使用
    • 5、finditer正则表达式方法,roup,span,start,end属性的使用
    • 6、finditer正则表达式对象方法,roup,span,start,end属性的使用
  • search和match方法的区别
    • 1、match方法的特点 :
    • 2、search方法的特点 :
  • 匹配中文:
  • 注意贪婪模式与非贪婪模式
    • (1)、使用贪婪的数量词
    • (2)、使用非贪婪的数量词

看这篇文章之前:我先提醒一下大家,所有的代码案例的输出结果均在print的后面,大家也不要放过每段代码后面的注释因为很多的信息都在注释中
正则表达式
正则表达式的应用在爬虫中很广泛,主要有以下操作!

页面解析和数据提取

一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值。内容
一般分为两部分,非结构化的数据 和 结构化的数据。
非结构化数据:先有数据,再有结构
结构化数据:先有结构、再有数据
不同类型的数据,我们需要采用不同的方式来处理。

1、非结构化数据处理
顾名思义,就是没有固定结构的数据。各种文档、图片、视频/音频等都属于非结构化数据。对于这类数据,我们一般直接整体进行存储,而且一般存储为二进制的数据格式。
正则表达式 HTML 文件 ∙
正则表达式
XPath
CSS选择器
文本、电话号码、邮箱地址:
“^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$”

^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$

2. 结构化的数据处理
结构化的数据是指可以使用关系型数据库表示和存储,表现为二维形式的数据。一般特点是:数据以行为单位,一行数据表示一个实体的信息,每一行数据的属性是相同的。举一个例子:

id      name    age     gender
1       lyh     12      male
2       liangyh 13      female
3       liang   18      male

所以,结构化的数据的存储和排列是很有规律的,这对查询和修改等操作很有帮助。但是,显然,它的扩展性不好(比如,我希望增加一个字段,怎么办?)
JSON 文件
JSON Path
转化成Python类型进行操作(json类) XML 文件
转化成Python类型(xmltodict)
XPath
CSS选择器
正则表达式
半结构化数据
半结构化数据是结构化数据的一种形式,它并不符合关系型数据库或其他数据表的形式关联起来的数据模型结构,但包含相关标记,用来分隔语义元素以及对记录和字段进行分层。因此,它也被称为自描述的结构。

半结构化数据,属于同一类实体可以有不同的属性,即使他们被组合在一起,这些属性的顺序并不重要。

常见的半结构数据有XML和JSON,对于对于两个XML文件,第一个可能有

<person><name>A</name><age>13</age><gender>female</gender>
</person>第二个可能为:<person><name>B</name><gender>male</gender>
</person>

实际上爬虫一共就四个主要步骤:
(1) 明确目标 (要知道你准备在哪个范围或者网站去搜索)
(2) 爬 (将所有的网站的内容全部爬下来)
(3) 取 (去掉对我们没用处的数据)
(4) 处理数据(按照我们想要的方式存储和使用)

什么是正则表达式

正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则) 的文本。 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字 符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表 达对字符串的一种过滤逻辑。
它能够表示一定的意义[字符串]的组合就是正则表达式。实际上正则表达式就是一个字符串

四大奇术:

在我看来有这四种东西大家一般人很难看懂;

医生的字:只有–>药剂师/医生能看懂
道士的符:只有–>道士能看懂
女人的心:只有–>女人懂
程序猿的正则:只有–>程序猿能看懂

正则表达式是咋来的?
1、 来源—unix操作系统。。。正则表达式 posix(bre和ere模式)
2、 python中使用的是prel。。。其他语言都有独特的正则语法。->prce正则
3、 常用的两大正则 posix系列和pcre系列
4、 prel【pcre】 c语言【posix】 phh【pcre/posix】python【pcre】
正则的作用?
1、 字符串过滤:在字符串获取需要的部分字符,比如:我只要数字,或者字母
2、 验证字符串:用户名,密码的命名相关输入规范,
3、 切割字符串:划分字符串内容
4、 替换字符串:替换文章相关的信息
5、 在我们学习的爬虫中会大量使用正则。
正则的组成:
原子,元字符,模式修正符 【其他语言中可能存在定界符】
原子:
1、所有可见字符都是原子:a,b,d,A,B,C,D,你,啦,-+!#@$#%&&&()(_+
2、所有不可见的字符也是原子:\t缩进符 \n换行 \r回车

正则常用的元字符列表:

元字符 含义
. 匹配除 “\n” 之外的任何单个字符。
^ 表示匹配的内容必须在整个字符串的开头部位.
$ 匹配输入字符串的结束位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 或 “does” 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。

原子的案例代码:


# 原子是正则表达式中匹配的最小单位# 因为正则表达式本质是字符串,单独使用是没有意义的,正则表达式需要配合相关的函数和方法使用
#导入re模块
import re
# search方法:查找符合正则表达式的内容,人任意位置开始查找,只匹配一次,匹配到了就返回一个Match对象# 准备正则pattern是正则的意思
# pattern = r'baidu'  # r表示字符串中的内容只是个普通的源字符串,它是为了防止\的转义字符# 正则查找的字符串
# url = 'http://ww.baidu.com'# 匹配操作
# result1 = re.search(pattern,url,) # 接收正则表达式和要匹配的字符串
# print(result1) # result1会返回一结果的对象 #<re.Match object; span=(10, 15), match='baidu'>
# span表示获取到的起始位置和结束位置
# match表示匹配到的内容
# 如果search匹配不到则返回一个None
# pattern = r'bai du' # None # 下匹配的话就会None
# print(result1.group())# 原子测试 所有的原子字符字匹配时只能匹配单个字符,
# 1、
pattern = r'\d' # \d只查找0-9的数字# 要查找的字符串
url1 = '13245 baidu.com'# 匹配操作
result2= re.search(pattern,url1) # 因为这里使用的search方法,所以这里只会匹配一次,且结果为一个的字符结果
print(result2) #<re.Match object; span=(0, 1), match='1'>
# 2、
pattern2 = r'\D'  # \D查找除了0-9之间的所有字符
result3 = re.search(pattern2,url1) # 由于使用的是Search方法所以值匹配一次,
print(result3) # <re.Match object; span=(5, 6), match=' '># 3、\s
pattern3 = r'\s' # 只匹配不可见字符
url2 ='46531dasd\t' # 比如一些转义字符和空格# 匹配
result3 = re.search(pattern3,url2)
print(result3) # <re.Match object; span=(9, 10), match='\n'>,# 4、\S # 只匹配可见字符
pattern4 =r'\S'
url2 = '\t46das\n'
# 匹配
result4 = re.search(pattern4,url2) # 这里的\t他就匹配不到,因为他是不可见字符
print(result4) #<re.Match object; span=(1, 2), match='4'># 5、 \w 只匹配0~9 ,a-z,A-Z和下划线中的任意一个字符
pattern5 = r'\w'url3 = '%$6da546'
result5 = re.search(pattern5,url3) # 因为%不在\W的匹配范围内所以,不符合要求
print(result5) #<re.Match object; span=(2, 3), match='6'># 6、\W只匹配0~9 ,a-z,A-Z和下划线之外的任意一个字符
pattern6 = r'\W'
url4 = '$%#dsa'
result6= re.search(pattern6,url4)
print(result6) # <re.Match object; span=(0, 1), match='$'># 7、 (.)表示可以匹配任何一个字符,什么都可以匹配,但是但是特别注意:它不能匹配\n因为它是换行字符pattern7 = r'.'
url5 ='\n$_01sa'
result7 = re.search(pattern7,url5)print(result7)
# <re.Match object; span=(0, 1), match='d'>
# <re.Match object; span=(0, 1), match='$'>
# <re.Match object; span=(0, 1), match='_'>

元字符:[原子修饰符]


(1)[] 中括号表示自定义原子列表
表示自定义原子列表中的任意一个字符,如果多个字符在ascii码中四连续的,可以进行缩写,例如[0123456789]–>[0-9]

正则专用字符:
\d 表示0~9之间任意[一个]字符
\D 表示除了0~9之外的任意【一个字符】
\s 表示任意【一个】空白字符(不可见字符)
\S 表示任意【一个】非空白字符 (可见字符)
\w 表示09,az,A~Z和()下划线中的任意【一个】字符
\W 表示除了09,az,A~Z和(
)之外的任意【一个】字符

如果我们想匹配不在\d或者其他正则表达式之外的字符时我们可以使用自定义原子列表,自己定义一个正则表达式:
\d 表示0~9之间任意[一个]字符 改为–>[0123465789]自定义原子列表格式,它和\d的意思是一样的

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200301194514901.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5emd6eXJtenNq,size_16,color_FFFFFF,t_70

(2)、看看自定义原子排除列表是什么
表示原子列表之外的任意一个字符,如果多个字符在ascii码中是连续的,可以进行缩写,例如[0123456789]–>[0-9]
未使用^(益阳符之前)
使用益阳符^之后

与数量相关的元字符的使用

1、+的使用:

表示1个或者1个以上修饰的原子
+可以修饰(匹配)+前面的这个原子,这个原子至少在字符串中有一个,或者多个,上不封顶,

import re
url6 ='ggle'
pattern6 = r'go+gle' #
result6 = re.search(pattern6,url6)
print(result6) # Noneurl7 = 'gogle'
pattern7 = r'go+gle' #
result7 = re.search(pattern7,url7)
print(result7) # <re.Match object; span=(0, 5), match='gogle'>url8 = 'goooooooogle'
pattern8 = r'go+gle' #
result8 = re.search(pattern8,url8)
print(result8) # <re.Match object; span=(0, 12), match='goooooooogle'>

2、?的使用:

表示匹配?前面的0个或者1个原子,?本身是个元字符,是用元字符来修饰原子,也就是在要查找的字符串中,?匹配它前面的一个原子,在字符串中只要没有这个原子即为0个,则它就会匹配?前面这个原子以外的字符串,如果?匹配它前面的一个原子,在字符串中只要有一个这个原子即为1个,则就会把带有这个原子的字符串匹配出来,如果?匹配它前面的一个原子,在字符串中有两个?(问号)前面的原子的话,那就返回None值

import re
# 3、?的使用表示重复匹配0个或者1个修饰的原子
pattern3 =r'go?gle' # ?元字符只能影响它前面的一个原子即(o)在字符串中的获取与否,url3= 'gogle'
result3 =re.search(pattern3,url3)
print(result3)# <re.Match object; span=(0, 5), match='gogle'>url4='google'
pattern4 = r'go?gle' #
result4 = re.search(pattern4,url4)
print(result4) #Noneurl5 ='ggle'
pattern5 = r'go?gle'
result5 = re.search(pattern5,url5)
print(result5) #<re.Match object; span=(0, 4), match='ggle'>

3、/*(星号)的使用

可以匹配任意的一个修饰的原子,匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。

import re# 5、*(星号的使用) # *可以匹配任意的字符,什么都可以匹配url7 = 'ggle'
pattern7 = r'go*gle' #
result7 = re.search(pattern7,url7)
print(result7) # <re.Match object; span=(0, 5), match='gogle'>
url13='gojihjghggle'
result8 = re.search(r'go*gle',url13)print(result8) # <re.Match object; span=(0, 12), match='goooooooogle'>url14 = 'gooooooooogleyfgh'result8 = re.search(r'go*gle',url14)
print(result8) # <re.Match object; span=(0, 12), match='goooooooogle'>url15 ='gooodogdsale'
result9=re.search(r'go*gle',url15)
print(result9)url8 = 'gooooooooooooooooooole'
pattern8 = r'go*le' #
result8 = re.search(pattern8,url8)
print(result8) # <re.Match object; span=(0, 12), match='goooooooogle'>

对中括号[]的详解:



[]中括号它也可以指定正则表达式获取的的范围。

对.和*和[]的进一步认识

import re
# 对.和*和[]的进一步认识
url8 = 'zbcdasda1234567/*.-+!~@!#@$$%%$^&*(*()'
pattern8 = r'[*]' #
result8 = re.findall(r'[*]',url8)
print(result8) # ['*', '*', '*']
result9 = re.findall(r'[\d]',url8)
print(result9) # ['1', '2', '3', '4', '5', '6', '7']
result10 = re.findall(r'[.*]',url8)
print(result10) # ['*', '.', '*', '*']
result11 =re.findall(r'[abcd]',url8)
print(result11) # ['b', 'c', 'd', 'a', 'd', 'a']
result12 =re.findall(r'.',url8)
print(result12) # ['z', 'b', 'c', 'd', 'a', 's', 'd', 'a', '1', '2', '3', '4', '5', '6', '7', '/', '*', '.', '-', '+', '!', '~', '@', '!', '#', '@', '$', '$', '%', '%', '$', '^', '&', '*', '(', '*', '(', ')']result12 =re.findall(r'.*',url8)
print(result12) #['zbcdasda1234567/*.-+!~@!#@$$%%$^&*(*()', '']
# result12 =re.findall(r'*',url8)
print(result12) # 报错
result8 = re.search(r'[.*]',url8)

4、{m}的使用,表示必须是m个修饰的原子

import re
# {m}的使用,表示必须是m个修饰的原子,也就是修饰{m}前面的这个原子
pattern15 = r'go{3}gle' # 获取的字符串必须是两个o,否则返回None
url15 = 'gooogle'
result15 = re.search(pattern15,url15)
print(result15) # None

5、{m,n}的使用:

表示修饰的原子数量是m到n之间的数量都可以(包含m也包含n)

import re
#{m,n} 的使用,表示必须是m到n个修饰的原子(也包含m和n),也就是{}前面的这个原子,
url16 = 'gooooogle'
pattern16 =r'go{2,5}gle' # 表示获取的字符串必须是2到5个字符之间的内容,
result16 =re.search(pattern16,url16)
print(result16) #<re.Match object; span=(0, 9), match='gooooogle'>
# 如果多与正则表达式的规则则返回None
url17 = 'goooooooooooogle'
result17 =re.search(pattern16,url17)
print(result17) # None

6、{m,}的使用:

表示修饰的原子数量是从m个到正无穷(包含m)

import re
# {m,}的使用 表示修饰的原子数量是从m个到正无穷(包含m),即:{m,}只修饰{m,}前面的这个原子,
# 如果字符串中有第m个字符则从这个字符开始往后取,有多少取多少
# 如果字符串中没有第m个字符则,则返回None
url19 = 'gooooooogle'
pattern19 = r'go{1,}gle'
result19 = re.search(pattern19,url19)
print(result19) #<re.Match object; span=(0, 11), match='gooooooogle'>

7、{,n}的使用

{,n}的使用 表示0-n个修饰的原子,(也包含0也包含n),逗号前面不写默认为0

import re
# {,n}的使用 表示0-n个修饰的原子,(也包含0也包含n),逗号前面不写默认为0
# 如果{,n}前面的原子在字符串多于n,则返回None
url20 = 'gooogle'
pattern20 = r'go{,7}gle'
result20 = re.search(pattern20,url20)
print(result20) # <re.Match object; span=(0, 7), match='gooogle'>url20 = 'gooooooooooooogle'
pattern20 = r'go{,7}gle'
result20 = re.search(pattern20,url20)
print(result20) # None# 注意:目前我们一直关注的只是o这个原子,但是其他的规则还是要记得,比如search方法只能匹配一次,如果符合正则表达式,
# 则返回结果,否则返回None

\A的使用:

表示获取的内容必须在整个字符串的开头部位

# 导入re模块
import re
# 准备正则表达式
# (1)、\A的使用,表示需要限定的内容必须在字符串的开头
# 在开头
pattern1 = r'\Ahttp' # 这里注意\A必须在要修饰的原子前面才可以,即:http的前面,否则返回None
# 正则查找的字符串
url1 ='http://www.google.com'
# 匹配操作
result = re.search(pattern1,url1)
print(result)# <re.Match object; span=(0, 4), match='http'># http不再在开头时,
pattern2 = r'\Ahttp'
# 正则查找的字符串
url2 ='谷歌http://www.google.com'
# 匹配操作
# 只要字符串中的内容不符合\A限定获取的,要求就会返回None,空值
result2 = re.search(pattern2,url2)
print(result2)#None

\Z的使用:

\Z的使用 表示需要限定的内容必须在字符串的尾部

import re
# (2)、\Z的使用 表示表示需要限定的内容必须在字符串的尾部
# com在尾部
pattern3 = r'com\Z' #这个与\A的位置则相反,它必须在要修饰的原子的后面,否则返回None
# 正则查找的字符串
url3 ='谷歌http://www.google.com'
# 匹配操作
# 只要字符串中的内容不符合\Z限定获取的,要求就会返回None,空值
result3 = re.search(pattern3,url3)
print(result3)#<re.Match object; span=(20, 23), match='com'># com不在尾部
pattern4 = r'com\Z' #这个\Z与\A的位置则相反,它必须在要修饰的原子的后面,否则返回None
# 正则查找的字符串
url4 ='谷歌http://www.google.comwww' #因为这里的com没有在字符串的尾部所以返回None
# 匹配操作
# 只要字符串中的内容不符合\Z限定获取的,要求就会返回None,空值
result4 = re.search(pattern4,url4)
print(result4)#None

多行模式

如果字符串中包含\n字符,则可以在匹配的时候使用多行匹配模式即,多行模式就是将每一行当中独立的字符串进行匹配,注意如果使用多行模式则必须使用多行模式修正符:re.M

^的使用:

表示获取的内容必须在整个字符串的开头部位.支持多行模式

import re
# (3)、^(益阳符)和\A的功能一样,但是有一点不同,^可以多行匹配,而\A不可以,
# http在开头
pattern5 = r'^http' # 大家注意:这里的^是在''(单引号中)使用的,所以和在[]中使用的效果是不一样的,这里的^只是单纯的匹配
# 需要限定的内容必须在字符串的开头,
# 正则查找的字符串
url5 ='http://www.google.com'
# 匹配操作
result5 = re.search(pattern5,url5)
print(result5)#<re.Match object; span=(0, 4), match='http'># http不再开头
pattern6 = r'^http' # 大家注意:这里的^是在''(单引号中)使用的,所以和在[]中使用的效果是不一样的,这里的^只是单纯的匹配
# 需要限定的内容必须在字符串的开头,
# 正则查找的字符串
url6 ='dsadashttp://www.google.com'
# 匹配操作
result6 = re.search(pattern6,url6)
print(result6)#None 匹配的内容不再开头则返回None# ^在有\n的情况下,即多行模式# 多行模式:如果字符串中包含\n字符,则可以在匹配的时候使用多行匹配模式即,多行模式就是将每一行当中独立的字符串进行匹配
# 注意如果使用多行模式则必须使用多行模式修正符:re.M
# 如果字符串中有\n换行符时,操作就不一样了,使用^即便开头不是需要匹配的内容但是只要有某一行的开头是需要匹配的内容,
# 则可以匹配成功,如果每一行的开头都不是需要匹配的内容,则返回None
pattern7 = r'^http' # 大家注意:这里的^是在''(单引号中)使用的,所以和在[]中使用的效果是不一样的,这里的^只是单纯的匹配
# 需要限定的内容必须在字符串的开头,
# 正则查找的字符串
url7 ='dsadas\nhttp://www.google.com'  # 注意这里加了\n
# 匹配操作
# 因为上面的字符串中有\n,并且是在使用^的情况下,所以这里必须使用多行匹配模式的的re.M,它是多行模式的模式修正符。
result7 = re.search(pattern7,url7,re.M)
print(result7)#<re.Match object; span=(7, 11), match='http'># 这里注意:\A不支持多行模式的匹配,^支持多行模式的匹配,使用\A在多行模式的情况下,它只会返回None

$的使用:

表示需要限定的内容必须在字符串的尾部,支持多行模式

import re
# 4、$ 的使用,$和\Z的功能一样,都是限定匹配的内容只能在字符串的尾部,否则返回None,但是它可以支持多行模式的匹配,
# 使用$在多行模式的情况向想要获取到相应的内容,就必须使用多行模式修正符:re.M,否则返回:None
# com在尾部
pattern8 = r'com$'
# 正则查找的字符串
url8 ='谷歌http://www.google.com'
# 匹配操作
# 只要字符串中的内容不符合$限定的内容,匹配的就会返回None,空值
result8 = re.search(pattern8,url8)
print(result8)#<re.Match object; span=(20, 23), match='com'># 不再尾部
pattern9 = r'com$' #表示限定的内容必须在整个字符串的结束部位,支持多行模式匹配
# 正则查找的字符串
url9 ='谷歌http://www.google.comxxx'
# 匹配操作
# 只要字符串中的内容不符合$限定的内容,匹配的就会返回None,空值
result9 = re.search(pattern9,url9,) #
print(result9)# None# $在\n多行模式的情况下使用
# com在字符串尾部
pattern10 = r'com\Z' #表示限定的内容必须在整个字符串的结束部位,支持多行模式匹配
# 正则查找的字符串,如果字符串中有\n则可以使用,$和多行模式一起使用,它在多行模式的情况下必须使用
# 多行模式修正符:re.M,才可以匹配到相应的内容
url10 ='谷歌http://www.googlcome.\ncomcom'
# 匹配操作
# 还是那句话,如果即便使用了多行模式,但是字符串中的内容不符合匹配的规则,依然获取不到,
result10 = re.search(pattern10,url10,re.M) # 这里必须使用re.M
print(result10)# <re.Match object; span=(21, 24), match='com'># 注意:虽然$和\Z的作用是一样的,但要记住,\Z不能在多行模式下使用,

\b的使用:

即词边界:表示这个元字符\b能够修饰它后面或者前的原子把这个原子进行分割,即:原子在字符串中,原子前面或者后面的除了,字母和数字,汉字之外的字符,都可以作为分割符,将这个原子分割出来

import re
# (5)、\b的使用即词边界:表示这个元字符\b能够修饰它后面的原子,把这个原子进与它前面的这个单词进行行分割,
# 即:原子在字符串中,原子前面的除了(字母和数字)的字符,都可以将这个原子,分割出来# 可以分割的情况下
#正则表达式
# 在\b在my前面,my前面没有字母和数字的情况下
pattern11 = r'\bmy' # \b的位置可以在原子的前面也可以是原子的后面,\b在原子的前面则表示,分割的是my前面的单词,就与在字符串中my前面
# 是不是字母和数字相关
# 正则匹配的字符串
url11 ='if you lose my self' # 因为my前面是不是字母和数字所以空格可以当做分割符,my能被分割出来
#返回的结果
result11 = re.search(pattern11,url11)
print(result11)# <re.Match object; span=(12, 14), match='my'># 在\b在my前面,my前面有字母的情况下
# 在被原子my被原子修饰符\b修饰的情况下,\b后面的这个my,现在要把它从字符串中分割出来,但是因为在字符串中my的前面是字母所以不能分割
# 在在字符串中,原子前面是字母的情况下,不能被分割,返回None
#正则表达式
pattern12 = r'\bmy'
# 正则匹配的字符串
url12 ='if you lose dmy self' # 因为my前面是字母所以字母不能当做分割符,my不能被分割出来
#返回的结果
result12 = re.search(pattern12,url12)
print(result12)# None# 在数字的情况下
# 在原子my被原子修饰符\b修饰的情况下,\b后面的这个my,现在要把它从字符串中分割出来,但是因为在字符串中my的前面是数字所以不能分割
# 在在字符串中,原子前面是数字的情况下,不能被分割,返回None
# 在\b在my前面,my前面有数字的情况下
#正则表达式
pattern13 = r'\bmy'
# 正则匹配的字符串
url13 ='if you lose 132my self' # 因为my前面是字母所以字母不能当做分割符,my不能被分割出来
#返回的结果
result13 = re.search(pattern13,url13)
print(result13)# None# 在\b在my后面的情况下,则分割的是my后面的单词,
# 在原子my被原子修饰符\b修饰的情况下,\b前面的这个my,现在要把它从字符串中分割出来,但是因为在字符串中my的后面是数字所以不能分割
# 在在字符串中,原子后面面是数字或者字母的情况下,不能被分割,返回None
# 在没有字母和数字的情况下,
pattern14 = r'my\b'
# 正则匹配的字符串
url14 ='if you lose 132my self' # 因为my后面没有字母和数字所以后面的空格可以当做分割符,my能被分割出来
#返回的结果
result14 = re.search(pattern14,url14)
print(result14)# <re.Match object; span=(15, 17), match='my'># 是字母的情况下,并且\b在my后面的情况下,
pattern15 = r'my\b'
# 正则匹配的字符串
url15 ='if you lose 132myself' # 因为my后面是字母所以字母不能当做分割符,my不能被分割出来
#返回的结果
result15 = re.search(pattern15,url15)
print(result15)#None# 是数字的情况下,并且\b在my后面的情况下,
pattern16 = r'\b'
# 正则匹配的字符串
url16 ='if you lose 132my1231*45self' # 因为my后面是数字所以字母不能当做分割符,my不能被分割出来
#返回的结果
result16 = re.search(pattern16,url16)
print(result16)#None# 这里注意:原子必须是字母或者是数字,分割符必须是,除字母数字,汉字之外的原子,都可以为分割符,汉字被当做字母处理# 如果\b在原子的前面和后面都有时,
# \bmy\b ,则表示在字符串中单独的将这个my单词分割出来,原子my在字符串中,它的前面和后面都不能有数字,字母,汉字pattern17 = r'\bmy\b'
# 正则匹配的字符串
url17 ='if you lose my 45self' # 因为my后面是数字所以字母不能当做分割符,my不能被分割出来
#返回的结果
result17 = re.search(pattern17,url17)
print(result17)#<re.Match object; span=(12, 14), match='my'>

\B的使用:

表示不能够当做英文单词分割的字符(非词边界,就是数字和字母,汉字作为字母处理)代表【一个】字符

import re
# (6)、\B表示不能够当做英文单词分割的字符(非词边界,就是数字和字母,汉字作为字母处理)代表【一个】字符# 如果在findall多次匹配的情况下,字符串中有多个my,而我只想要第一个my,则可以在单词的前面使用\b,在单词的后面使用\Bpattern18 = r'\bmy\B'
# 正则匹配的字符串
url18 ='if you mylosemy45semylf' # 因为my后面是数字所以字母不能当做分割符,my不能被分割出来
#返回的结果
result18 = re.findall(pattern18,url18)
print(result18)#['my'] 返回一个列表

|竖线的使用:

表示选择关系,左右的内容二选一,非常重要,因为|是正则表达式中基本上是唯一的运算关系内容

# 导入包
import re#准备正则表达式
pattern = r'ab|cd'  # 它表示的意思为:在字符串中匹配时,只匹配|(竖线)左右两边的完整的内容,
# 不会匹配单个原子,或者交换匹配多个原子比如:acd,cda# 正则查找的字符串
url1 = '我喜欢的字母是cad'
# 字符串中的与正则表达式中的原子没有相对应时,为单个原子时,则返回None
# 匹配操作
result1 = re.search(pattern,url1)
print(result1)# 字符串中的与正则表达式中的原子没有相对应时,为多个原子时,但是只要里面有|两边完整的内容。则会返回其中一个完整的内容
pattern2 = r'ab|cd'  # 它表示的意思为:在字符串中匹配时,只匹配|(竖线)左右两边的完整的内容,# 正则查找的字符串
url2 = '我喜欢的字母是cddac'# 匹配操作
result2 = re.search(pattern2,url2)
# 只会匹配完整的内容
print(result2) # <re.Match object; span=(7, 9), match='cd'>

()小括号的使用:

1、 改变正则表达式中的优先级
2、 将多个原子视为一个原子处理,方便使用元字符,【可以叫做组或者模式单元】
3、 将匹配的内容当做模式单元进行存储(这个会在另外的小结中说明,这里暂时不提)

(1)、改变正则表达式中的优先级

import re
#()的使用
# 1、改变正则表达式中的优先级
pattern3 = r'a(b|c)d' # 匹配只能abd或者acd
# 括号里面指的是,先匹配b或者c,然后匹配外面的a和d,然而a和d是必须匹配的所以,匹配的内容必须是abd或acd否则None# 这里是相对应匹配的字符
# 正则查找的字符串
url3 = 'abdacd'
# 匹配操作
result3 = re.search(pattern3,url3)
# 只会匹配左右任意一边完整的内容
print(result3) ## 这里是没有与之相对应的字符
pattern3 = r'a(b|c)d' # 匹配只能abd或者acd
# 括号里面指的是,先匹配b或者c,然后匹配外面的a和d,然而a和d是必须匹配的所以,匹配的内容必须是abd或acd否则None# 正则查找的字符串
url3 = 'acbadbbad'
# 匹配操作
result3 = re.search(pattern3,url3)
# 只会匹配完整的内容
print(result3) #None

(2)、将多个原子视为一个原子处理,方便使用元字符,【可以叫做组或者模式单元】

import re#2、将多个原子视为一个原子处理,方便使用元字符,【可以叫做组或者模式单元】
# 比如我想要获取http://www.gogogogogogole.com这样的字符,该怎么办呢?# 首先我们试着使用一下go+
pattern4 = r'go+gle'
url4 = 'http://www.gogogogogogogle.com'
# 匹配操作
result4 = re.search(pattern4,url4)
# 虽然是可以获取的到,但是与我们想要的还是不同的
print(result4) #<re.Match object; span=(21, 26), match='gogle'># 加上小括号()试试
pattern4 = r'(go)+gle'
url4 = 'http://www.gogogogogogogle.com'
# 匹配操作
result4 = re.search(pattern4,url4)
# 加上了小括号之后,我们就得到了结果,所以()的另外一个作用,是吧小括号当中的内容看做是一个原子,或者叫组,模式单元,
# 在这里,也就是让go这两个原子一起往后获取,有多少获取多少
print(result4) #<re.Match object; span=(11, 26), match='gogogogogogogle'>

模式修正符:

设定匹配的一些额外的规则

re.A的使用:

re.A的使用,或者可以写成re.ASCII 在ASSCII码模式下进行匹配操作

# 模式修正符
import re
# 1、re.A的使用,或者可以写成re.ASCII 在ASCII码模式下进行匹配操作
# 在没有使用re.ASCLL的情况下
pattern1 =r'\w+'  # 匹配0-9,a-z,A-Z和(_)下划线的字符
# 正则查找的字符串
url1 ='我love你他love我我也love大家'# 匹配操作
result = re.findall(pattern1,url1,)
# 因为在这里会把汉字当做字符串来处理所以可以输出汉字
print(result)# ['我love你他love我我也love大家']# 使用re.A
pattern2 =r'\w+'  # 匹配0-9,a-z,A-Z的字符
# 正则查找的字符串
url2 ='我love你他love我我也love大家'# 匹配操作
result2 = re.findall(pattern2,url2,re.A) #
# 因为在ASCLL情况下,不会把汉字当做汉字来处理所以不可以输出汉字
print(result2)#['love', 'love', 'love']

re.U的使用:

re.U的使用,或者可以写成re.UNICODE 在UNICODE码模式下进行匹配操作

import re
# re.U的使用,
pattern3 =r'\w+'  # 匹配0-9,a-z,A-Z的字符
# 正则查找的字符串
url3 ='我love你他love我我也love大家'# 匹配操作
result3 = re.findall(pattern3,url3,re.U) #
#其实我们在使用print输出python3默认使用的是UNICODE码,所以这里使用了re.U和不有使用是没有区别的
print(result3)#['我love你他love我我也love大家']

re.S的使用:

re.S的使用,使得原子(.)点,可以匹配任意字符包含\n

import re
# re.S的使用,
# 未使用re.S时
pattern4 =r'a.b'  # .匹配任意的字符,除了\n
# 正则查找的字符串
url4 ='adad\ndab'# 匹配操作
result4 = re.findall(pattern4,url4,) #
print(result4)#[]# 使用了re.S时
pattern4 =r'a.b'  # .匹配任意的字符,除了\n
# 正则查找的字符串
url4 ='a\nb' # 注意如果要匹配\n时,在正则表达式中不可以使用r,因为它是为了防止转义的
# 匹配操作
result4 = re.findall(pattern4,url4,re.S) #在这里添加了re.S之后,就可以配到\n了
print(result4)#['a\nb']

re.m的使用:

re.m的使用:re.M或者re.MULTILINE 匹配操作在多行模式下进行 都是与^和$相关的操作!

import re
# 4、re.M的使用,re.M或者re.MULTILINE  匹配操作在多行模式下进行 都是与^和$相关的操作!
pattern5 =r'^www'  # 只匹配头部为www开头的字符串,
# 正则查找的字符串
url5 ='www.com\nwww.com'# 匹配操作
result5 = re.findall(pattern5,url5,re.M) #re.M回合^和$结合使用。所以这里带有\n的在多行模式下,也可以匹配到相应的字符
print(result5)#['www', 'www']# 使用$时
pattern6 = r'com$' # 只匹配以com结尾的字符串,可以在多行模式下操作# 正则查找的字符串
url6 = 'www.com\nwww.com'
result6 = re.findall(pattern6,url6,re.M)print(result6) # ['com', 'com'] # 结合re.M的使用可以获取到\n后面的符合要求的内容

re.x的使用:

re.x的使用:re.X或者re.VERBOSE 匹配的时候忽略正则表达式中的空格或者注释

import re# 5、re.X的使用:re.X或者re.VERBOSE 匹配的时候忽略正则表达式中的空格或者注释
# 使用re.X后
pattern6 = r'co m #dasd' # 忽略正则表达式中与com不相干的内容,比如我们只查找com,但是正则表达式中有可能有会有一些其他的
# 字符,或者是注释,这时我们可以使用re.X忽略正则表达式中的空格或者注释# 正则查找的字符串
url6 = 'www.com\nwww.comdas'result6 = re.findall(pattern6,url6,re.X)
# 如果我们不使用re.X时,这将获取不到内容,因为正则表达式中的内容,在字符串中匹配不到,字符串中的内容不符合要求,
# 但是使用了re.X时就不需要担心这一点了!
print(result6) #['com', 'com']

re.I的使用:

re.I的使用:re.I或者re.IGNPRECASE 匹配过程中忽略大小写!

import re
# re.I的使用:re.I或者re.IGNPRECASE 匹配过程中忽略大小写!# 不使用re.I时
# 正则表达式
pattern8 = r'com'url8 = 'HTTP://WWW.COMwww.com'result8 = re.findall(pattern8,url8)
#这里只能匹配到com
print(result8) # ['com']# 使用re.I时
pattern8 = r'com'url8 = 'HTTP://WWW.COMwww.com'result8 = re.findall(pattern8,url8,re.I)
#它就不区分大小写,把大小写comCOM都匹配出来
print(result8) # ['COM', 'com']

转义字符的应用:

字符串:\n \r \t \
因为在正则的元字符和和原子当中,使用了部分的符号作为语法,为了匹配这些符号的单纯字符格式,在正则表达式中用,添加(反斜杠)即可去掉意义,获取字符
比如下面的例子:

# 导入re
import re#1、反斜杠\的使用# 没有使用\时
# 正则表达式
pattern1 = r'www.baidu.com'# 正则匹配的字符串
url1= 'http://www1baidu1com'# 进行匹配操作
# 这里我们在匹配时可以看到,本来字符串中它是不符合正则表达式中的内容的,但是因为.(点)在正则表达式中,
# 它什么字符都可以匹配,所以即便www的后面是个1,由于url1中的点(.),所以.可以匹配到1,
result1 = re.search(pattern1,url1)
# 执行操作
print(result1) #<re.Match object; span=(7, 20), match='www1baidu1com'>#使用\时pattern2 = r'www\.baidu\.com'# 正则匹配的字符串
url2= 'http://www1baidu1com'# 进行匹配操作
# 这时我们可以看到,在.(点)的前面使用了\后,就匹配不到相应的字符了,因为\把.的作用转义了,使.(点)的功能
# 失效了,此时.(点)只是一个普通的字符,所以这里获取不到了
result2 = re.search(pattern2,url2)
# 执行操作
print(result2)#None# 2、\反斜杠的再次使用
# 未使用\前
pattern3 = r'[百度]' #这里的意思:匹配'百'或者'度'
# 正则匹配的字符串
url3= 'http://www1baidu1com[百度]'
# 进行匹配操作
result3 = re.search(pattern3,url3)
# 执行操作
# 为什么这里只能匹配到一个'百'呢?,因为[]中括号在正则表达式中他也会起到它本身的作用,
# 即:[]中括号的意思,它会认为你要匹配的是'百',或者'度'其中一个字符。所以这里只匹配了‘百’
print(result3)#<re.Match object; span=(21, 22), match='百'># 使用\反斜杠,让[]中括号的功能失效
pattern4 = r'\[百度\]'# 正则匹配的字符串
url4= 'http://www1baidu1com[百度]'# 进行匹配操作
result4 = re.search(pattern4,url4)
# 执行操作
# 当我们使用了\时,此时的[]中括号,就成了普通的字符,所以可以匹配到[百度]了
print(result4)#<re.Match object; span=(20, 24), match='[百度]'>

扩展正则语法:

1、(?Limsuxa)这是模式修正符的第二种应用方法

import re# 模式修正符的另外一种操作
# 正则表达式
pattern1 = r'baidu'# 正则匹配的字符串
url1 ='http://www.BAIDUbaidu.com'
# 匹配操作
# 我们要获取大写的百度时,则在这里添加上模式修正符re.I即可,
result1 =re.search(pattern1,url1,re.I)
# 输出
print(result1) #<re.Match object; span=(11, 16), match='BAIDU'># 我们不使用re.I,还有其他的方法获取大写吗?
# 这时我们可以在正则表达式中使用扩展正则语法的模式修正符,使用用它时需要戴上小括号
# 在括号中我们可以设置多个模式修正符,比如
pattern1 = r'(?ixm)bai    du' #其中括号中的模式修正符(?ixm)与re.这样的模式修正符效果是一样的# 正则匹配的字符串
url1 ='http://www.BAIDU\nbaidu.com'
# 匹配操作
# 在这里我们不使用re.I进行获取大写
result1 =re.search(pattern1,url1,)
# 输出
# 使用扩展语法的模式修正符,直接在正则表达式中使用即可
print(result1) #<re.Match object; span=(11, 16), match='BAIDU'>

2、(?:)的使用:取消单元存储功能

如果在正则表达式中被()小括号括起来的内容,就是一个单元模式,并且它会自动存储。
在使用search方法输出结果时,匹配的结果是一个match对象
而我们要把结果对象中的模式单元打印出来
在这里我们可以使用groups来打印结果中的模式单元
因为被小括号套了起来的内容成为了一个模式单元,所以这里在打印模式单元时就可以了,
使用groups的意思是将(‘du’)这个打印出来,

这里涉及到了小括号的第3个作用:
将匹配的内容当做模式单元进行处理

import re
# 2、(?:)的使用:它会取消单元存储功能# 存储模式单元
# 正则表达式
pattern3 = r'bai(du)' #这里的()小括号的另外一个作用为,如果给正则表达式中的某个元字符套上了()小括号
# 则表示,这个括号中的内容就是模式单元,(它自带存储工功能)# 正则匹配的字符串
url3 ='http://www.baidu.com'
# 匹配操作
#
result3 =re.search(pattern3,url3,) #result匹配的结果是一个match对象
# 输出。我们要把结果对象中的模式单元打印出来
# 在这里我们可以使用groups来打印结果中的模式单元
# 因为上面的du被小括号套了起来()小括号中的内容成为了一个模式单元,所以这里在打印模式单元时就可以了,
# 使用groups的意思是将('du')这个模式单元打印获取出来,并不是存储它,因为模式单元自带存储功能
print(result3.groups()) # ('du',)# 取消存储模式单元
# 正则表达式
# 在有些如果我们只是想让()改变优先级或者当做把多原子当做单原子处理,这时我们可以使用,(?:),取消存储单元模式
# 我们这里使用了(?:),它可以把(du)这个模式单元在使用groups进行存储时,取消它的存储,就可以节省内存资源
pattern4 = r'bai(?:du)+' #这里的()小括号的另外一个作用为,如果给正则表达式中的某个元字符套上了()小括号
# 则表示,这个括号中的内容就是模式单元(它自带存储工功能)# 正则匹配的字符串
url4 ='http://www.baidudududuudud.com'
# 匹配操作result4 =re.search(pattern4,url4,) #result匹配的结果是一个match对象
#因为我们使用了(?:)所以就达到了我们,只想把多个原子当做单个原子使用的目的,
# 而它('du')即便有个小括号,也不会进行单元存储,而这样就节省了内存资源
print(result4)
print(result4.groups()) # () # 这是groups就不会进行打印模式单元了,也不会进行存储

3、(?P<name>):的使用

自定义模式单元的名称

import re
# 3、(?P<name>):自定义模式单元的名称
# 如何匹配<title>百度</title>
pattern5 = r'<[a-z]+>.*</[a-z]+>' #这里的()小括号的另外一个作用为,如果给正则表达式中的某个元字符套上了()小括号
# 则表示,这个括号中的内容就是模式单元(它自带存储工功能)# 正则匹配的字符串
url5 ='<title>百度</title><body>www.baidu.com</body>'
# 匹配操作result5 =re.search(pattern5,url5,) #result匹配的结果是一个match对象
# 输出的结果貌似与我们的想象中的不一样
print(result5)# <re.Match object; span=(0, 43), match='<title>百度</title><body>www.baidu.com</body>'># 使用\1索引模式单元的应用# 我们使用()把[a-z]+中的内容变为模式单元后,它就会存储到模式单元的元组当中,
# 但是我们可以在正则表达式的后面把前面的这个模式单元取出来,在</>中加上索引\1即可获取到<[a-z]+>的内容,
# 注意group打印出来的内容在元组中,内容的下标1就是第一个内容,2就是第二个内容,这与我么所学习的以前的下标有所不同
# \1的意思即是:\1要求它与前面的<[a-z]+>中的内容一模一样,所以后面的</\1>把前面的<[a-z]+>中的内容复制到了</>中,
# <>和</>中的内容就一样了,这就是索引单元模式。
pattern6 = r'<([a-z]+)>.*</\1>' #这里的()小括号的另外一个作用为,如果给正则表达式中的某个元字符套上了()小括号
# 则表示,这个括号中的内容就是模式单元(它自带存储工功能)# 正则匹配的字符串
url6 ='<title>百度</title><body>www.baidu.com</body>'
# 匹配操作result6 =re.search(pattern6,url6,) #result匹配的结果是一个match对象
# 这次输出的结果就可以了
print(result6) #<re.Match object; span=(0, 17), match='<title>百度</title>'>
print(result6.groups()) # 打印()中的模式单元以元组的形式即:('title',)

4、(?P=name):

获取自定义模式单元的名称

import re
# 3、使用(?P=name) 获取自定义模式单元的内容# 虽然上面解决了我们的要求,但是一旦数据多了起来。这样的话就容易倒错顺序。
# 所以这里我们引入了字典模式单元,使用它就不会出错了
# 使用自定义模式单元,我们在存储模式单元时,不使用元组的形式存储,而是使用字典的格式存储,
#在这里我们使用自定义模式单元,(?P<biaoti>),在<>尖括号中的内容是字典的键,可以自己随便起名,
# 在这样的情况下就不用怕数据多了,因为再多的数据我有名称啊,不会乱的
# 如果我们要在正则表达式</>中取出这个以名称存储的模式单元的话,我们可以使用(?P=name)
# 这里后面的</(?P=biaoti)>的意思是,取出以自定义模式单元存储的这个字典格式的模式单元,#(小括号的第3个作用)
pattern7 = r'<(?P<biaoti>[a-z]+)>.*</(?P=biaoti)>' #这里的()小括号的另外一个作用为,如果给正则表达式中的某个元字符套上了()小括号
# 则表示,这个括号中的内容就是模式单元(这里是的模式单元为字典模式单元自带字典模式单元存储工功能)# 正则匹配的字符串
url7 ='<title>百度</title><body>www.baidu.com</body>'
# 匹配操作result7 =re.search(pattern7,url7,) #result匹配的结果是一个match对象
# 这次输出的结果就可以了
print(result7) #<re.Match object; span=(0, 17), match='<title>百度</title>'>
print(result7.groupdict()) # 打印()中的模式单元以字典的格式即:{'biaoti': 'title'}

5、(?#):

可以在正则表达式中写注释的内容,解释器不会处理该内容

import re
# 5、(?#):正则注释内容,我们再写正则表达式的时候,也可以添加注释
# (?#)它在正则表达式中的出现,只是一个注释则作用,并不会影响到其他符号的使用pattern7 = r'(?i)baidu(?#我就是个注释)'
# 正则匹配的字符串
url7 ='<title>百度</title><body>BAIDU baidu.com</body>'
# 匹配操作result7 =re.search(pattern7,url7,) #result匹配的结果是一个match对象
# 因为这里的(?#)只是个注释,所以不会对结果有是有什么影响!
print(result7)#<re.Match object; span=(23, 28), match='BAIDU'>

6、(?=):正向先行断言 (零宽断言)

什么是正向负向?什么是先行后行?
正向有 --> 负向–>相当于没有
先行–> 向前/向右进行查找 后行–>向后/向左进行查找

# 导入re
import re
# 1、(?=)的使用  正向先行断言 (零宽断言)
# 什么是正向负向?什么是先行后行?
# # 正向有      负向相当于没有
# # 先行  向前/向右进行查找    后行向后/向左进行查找# 正则表达式
# 这里的正向表示的即为:如果lmonkey原子的后面有.com这个原子的话,那就能匹配到lmonkey这个原子,否则匹配不到
# 先行表示:向右查找,如果在lomnkey的右边有.com的话,则可以在字符串中匹配到lmonkey这个字符串
pattern1 = r'lmonkey(?=\.com)'# 正则匹配的字符串
# 这里虽然有这么多的lmonkey,但是因为使用了(?=)正向现行断言,所以在查找时,就会以(?=)元字符修饰的原子.com来作为查找的标识,
# 如果lmonkey的后面有这个.com这个标识,则可以匹配到lmonkey这个字符串,否则匹配不到
url1= 'www.lmonkey.com www.lmonkey.ce www.lmonkey.net www.lmonkey.lal'# 匹配操作
result1 = re.search(pattern1,url1)
# 输出,只输出:4,11的lmonkey
print(result1) #<re.Match object; span=(4, 11), match='lmonkey'># 我们把lmonkey.com换个位置,看看是否可以证明使用了(?=)先行断言后,是否是以.com作为标识来查找的
pattern2 = r'lmonkey(?=\.com)'
# 正则匹配的字符串
url2= 'www.lmonkey.cm www.lmonkey.ce www.lmonkey.net www.lmonkey.com'
# 匹配操作
result2 = re.search(pattern2,url2)
# 输出,只输出: 此时它获取的是50,57的lmonkey,因为是以.com来作为标识的,有则匹配,没有则不匹配
print(result2) #<re.Match object; span=(50, 57), match='lmonkey'>

7、(?!):负向先行断言(零宽断言)

# 2、(?!):负向先行断言(零宽断言)
# 什么是正向负向?什么是先行后行?
# # 正向有      负向相当于没有
# # 先行  向前/向右进行查找  后行向后/向左进行查找
# (?!):相当于如果lmonkey的后面没有这个.com,则可以匹配到否则不可以,与正向先行断言相反
pattern3 = r'lmonkey\d(?!\.com)' # \.的意思是,因为.如果不转义的话,只要是个com它就会匹配到,不管com的前面是否有这个.只要字符串中的com
# 前面有个字符他就可以匹配到,转义后它只是个单纯的字符串(.)
# 正则匹配的字符串
url3= 'www.lmonkey1.cm www.lmonkey2.ce www.lmonkey3.net www.lmonkey4.com'
# 匹配操作
result3 = re.findall(pattern3,url3)
# 输出,此时它获取的是的只要lmonkey的后面没有.com,则获取,因为是以.com来作为标识的,没有则匹配,有则不匹配
print(result3) #['lmonkey1', 'lmonkey2', 'lmonkey3']

8、(?<=):正向后行断言(零宽断言)

import re
# 3、(?<=):正向后行断言(零宽断言)# 什么是正向负向?什么是先行后行?
# # 正向有      负向相当于没有
# # 先行  向前/向右进行查找  后行向后/向左进行查找
# 注意因为是后行,要向左查找,所以我们的元字符(?<=one\.)要放到原子(lmonkey)的左边,
#如果lmonkey的前面(后行)有(正向)这个one.则就可以匹配到,否则不能匹配到
pattern4 = r'(?<=one\.)lmonkey\d' # \.的意思是,因为.如果不转义的话,只要是个com它就会匹配到,不管com的前面是否有这个.只要字符串中的com
# 前面有个字符他就可以匹配到,转义后它只是个单纯的字符串(.)
# 正则匹配的字符串
url4= 'www.lmonkey1.cm www.lmonkey2.ce one.lmonkey3.net www.lmonkey4.com'
# 匹配操作
result4 = re.search(pattern4,url4)
# 输出,此时它获取的是的只要lmonkey的前面有one.则获取,因为是以.one来作为标识的,有则匹配,没有则不匹配
print(result4) #<re.Match object; span=(36, 44), match='lmonkey3'>

9、(?<!):负向后行断言(零宽断言)

import re
# 4、(?<!):负向后行断言(零宽断言)
# 什么是正向负向?什么是先行后行?
# # 正向有      负向相当于没有
# # 先行  向前/向右进行查找  后行向后/向左进行查找#如果lmonkey的前面(后行),没有(负向)这个(one.)则就可以匹配到,否则不能匹配到
# 注意因为是后行,要向左查找,所以我们的元字符(?!)要放到原子(lmonkey)的左边,
pattern5 = r'(?<!one\.)lmonkey\d' # \.的意思是,因为.如果不转义的话,只要是个com它就会匹配到,不管com的前面是否有这个.只要字符串中的com
# 前面有个字符他就可以匹配到,转义后它只是个单纯的字符串(.)
# 正则匹配的字符串
url5= 'www.lmonkey1.cm www.lmonkey2.ce one.lmonkey3.net www.lmonkey4.com'
# 匹配操作
result5 = re.findall(pattern5,url5)
# 输出,此时它获取的是的只要lmonkey的前面没有(one.)这个标识则获取,因为是以.one来作为标识的,没有则匹配,有则不匹配
print(result5) #['lmonkey1', 'lmonkey2', 'lmonkey4']

10、零宽断言先行和后行注意事项

import re
#5、零宽断言先行和后行注意事项
# 1、同时存在先行和后行,这里是正向后行和正向先行
# #如果lmonkey的前面(后行),有(正向)这个(one.),并且
# lmonkey的后面(先行),必须有(正向)这个(com.)则就可以匹配到,否则不能匹配到
pattern6 = r'(?<=one\.)lmonkey\d(?=\.com)' # \.的意思是,因为.如果不转义的话,只要是个com它就会匹配到,不管com的前面是否有这个.只要字符串中的com
# 前面有个字符他就可以匹配到,转义后它只是个单纯的字符串(.)
# 正则匹配的字符串
url6= 'www.lmonkey1.cm www.lmonkey2.ce one.lmonkey3.com www.lmonkey4.com'
# 匹配操作
result6 = re.search(pattern6,url6)
# 输出,此时它获取的是的只要lmonkey的前面有(one.)这个标识则获取并且lmonkey的后面必须有com.这个标识,
# 因为是以.one和com.是用来作为标识的,有这样的字符串则匹配,没有则不匹配
# 而此时只有lmonkey3一个符合标准
print(result6) #<re.Match object; span=(36, 44), match='lmonkey3'>

11、零宽断言的后行注意事项

宽度必须指定,不能是可变宽度

import re
# 零宽断言的后行注意事项,宽度必须指定,不能是可变宽度
# 这里在注意:后行中的aaa不可以为a+,因为后行中指定的标识只能是固定的长度,否则则会报错,{3},aaa也可以,但是{3,5},a+都不可以
pattern7 = r'(?<=a+\.)lmonkey\d(?=\.com)' # \.的意思是,因为.如果不转义的话,只要是个com它就会匹配到,
# 不管com的前面是否有这个.只要字符串中的com
# 前面有个字符他就可以匹配到,转义后它只是个单纯的字符串(.)
# 正则匹配的字符串
url7= 'www.lmonkey1.cm www.lmonkey2.ce aaa.lmonkey3.com www.lmonkey4.com'
# 匹配操作
result7 = re.search(pattern7,url7)
# 输出,此时它获取的是的只要lmonkey的前面有(one.)这个标识则获取并且lmonkey的后面必须有com.这个标识,
# 因为是以.one和com.是用来作为标识的,有这样的字符串则匹配,没有则不匹配
# 而此时只有lmonkey3一个符合标准
print(result5) #<re.Match object; span=(36, 44), match='lmonkey3'>

12、(?(id/name)Y|N):

根据模式单元是否存在决定使用Y的规则(模式单元存在)或者是N的规则(模式单元不存在)

import re
# 6、(?(id/name)Y|N):根据模式单元是否存在决定使用Y的规则(模式单元存在)或者是N的规则(模式单元不存在)pattern8=r'(www)?(?(1).*|\w+\.)' # # 目前(www)表示为一个原子,
# (www)?表示如果这个(www)模式单元在字符串中为0个时,则会匹配?(问号)前面这个原子即(www)模式单元以外的字符,
# 如果为这个(www)模式单元在字符串中为1个时,则匹配出这个模式单元并存储,(?(1))表示如果前面(www)?这个模式单元被?判断为1,
# 也就是(www)被存储起来后,
# 则匹配.*的内容,.*表示匹配所有的字符。|\w+\.表示,首先|表示或者的意思,如果前面的(www)没有被?判读为(1),则匹配\w+\.的内容,
# 即为匹配.前面的内容,或者是wwwww或者是其他的# 首先请看单元模式为0时是因为字符串中没有三个www,只有一个或者两个或者是其他的字符,就会匹配?(问号)前面这个原子即(www)模式单元以外的字符即(只有一个或者两个w或者是其他的字符)
# ,则后面匹配的是N,也就是\w+\.的内容,即匹配.前面的字符
url8='w.monkey.com'result8=re.search(pattern8,url8)
# 因为没有匹配到所以输出\w+\.匹配的内容
print(result8) # <re.Match object; span=(0, 2), match='w.'># 当(www)模式单元在字符串中为1个时,也就是字符串中有这三个字符(www),则匹配的是.*中的内容
# 本人目前认为(?(1))这里面的正则貌似对整个匹配没什么作用,全看(www)?的结果,如果获取到则输出.*的内容,否则为\w+\.的内容
pattern9 = r'(www)?(?(1).*|\w+.\)'
url8='www.monkey.com'result8=re.search(pattern8,url8)
# 因为这里匹配到了所以输出.*匹配的内容
print(result8) # <re.Match object; span=(0, 14), match='www.monkey.com'>

正则表达式的实例书写

1、qq邮箱的设定

# 1、用户名的设定#a设定规则(有字母,必须有9个以上10个以下,不可以有下划线和字母特殊字符)# b.书写一些符合规则的实例
'''2332399914@qq.com2454260219@qq.com'''
class QQcom(object):def __init__(self,qq):self.qq=qqself.run(self.qq)def run(self,qq):# 书写正则pattern=r'^\d{9,10}@qq.com$' # 表示的是以9到10个数字和@qq.com开头,也以9到10个数字和@qq.com结尾,# 这样就不能匹配到有下划线和字母特殊字符的qq邮箱号码喽result1=re.search(pattern,qq)print(result1)if __name__ == '__main__':qqphone=input('请输入你的qq邮箱')qqcom=QQcom(qqphone)# 验证
# 错误的
# 请输入你的qq邮箱2332399914@qq.dasd
# None
# 正确的
# 请输入你的qq邮箱2332399914@qq.com
# <re.Match object; span=(0, 17), match='2332399914@qq.com'>

2、IP地址的设定

a、设定规则(四个数字段,每个数字段使用.分割;数字范围0~255)
b、书写一些符合规则的地址

import re
# 2、ip地址的匹配# a、设定规则(四个数字段,每个数字段使用.分割;数字范围0~255)
# b、书写一些符合规则的地址
'''
192.168.0.1
127.0.0.1
0.0.0.0
255.255.255.255
'''# 书写正则# 首先我们匹配的是192.168.0.1
'''分析:1、因为四组数据都是一样的所以我们可以先匹配第一组数列,后面的进行重复即可2、对四组数据中的一组数据,也就是三位数的规定,首先不可使用r'\d'和r'd+',r'\d+{1,3}',并且三位数之间要以(.)来分割(1)、\d只能匹配一位数不符合,(2)、\d+匹配的就太多了,99999也可作为ip地址了,也不符合,(3)、\d+{1,3}即便它匹配的只是三位数,可以ip地址只能从0到255,所以不符合3、因为上面的不符合,所以我们要对这三位数进行拆分处理,每位数之间使用(|)竖线来分割,即表示或者(1)、如果只为一位数的话:\d即可(2)、如果是两位数,可以写\d{2}吗,不可以,因为ip地址没有01,02,03,04这么一说,只能从10~99所以我们可以这样写两位数:首先第一位数为[1-9]第二位数为\d,这样就成为了从一开始计算10到99即:[1-9]\d(3)、如果是三位数,首先三位数的第一种情况以1开头的三位数即:1\d{2},表示为:100-199第二种情况以2开头的三位数并且第二位是0-4,那么第三位就可以是0-9了,即:2[0-4]\d表示为:200-249如果以2开头的第二位是5的话那么ip地址就不能选0-4的数字了,所以为2[0-4]\d第三种情况是如果前面的数字为0-249的话,那么后面的以2开头第二为只能为5了,第三位也只能为[1-5]了即:25[0-5]注意切记一组数据写完后要以.来分割第一组数据的正则表达式:r'((?:\d(?#1位数))|(?:[1-9]\d(?#2位数))|(?:1\d{2}(?#3位数100-199))|(?:2[0-4]\d(?#3位数200-249))|(?:25[0-5](?#250-255)))\.'(1)、为了看起来简洁些可以给它套个括号并且不会被存储为模式单元(2)、虽然套上了括号看起来好看了些,但是要注意:如果没有给它们这么多的表达式套上一个整体的括号的话,\.会认为前面的套了括号的表达式是一个整体,因为字符直接的关系要比|(或)高,所以我们要把前面的所有的表达式给他们这个整体套上一个小括号即:r'((?:\d)|(?:[1-9]\d)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))\.'
'''
# 测试结果
# 正则表达式
pattern=r'((?:\d)|(?:[1-9]\d)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))\.' #
# 字符串
url1='00.'
# 匹配操作
result1=re.search(pattern,url1)
# 输出,首先0.是可以匹配的
print(result1) # <re.Match object; span=(0, 2), match='0.'>#2、输出,00.目前也可以匹配的
pattern2=r'((?:\d)|(?:[1-9]\d)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))\.' #
# 字符串
url2='00.'
# 匹配操作
result2=re.search(pattern2,url2)
# 输出的是0.但是它把前面的一个0忽略掉了,那是因为我们没有加首尾的限制,
print(result2) # <re.Match object; span=(1, 3), match='0.'># 3、当我们加上了首尾限制后,不可以输出00.因为我们设定的IP必须是以10开头,00已经超出了范围
pattern3=r'(^(?:\d)|(?:[1-9]\d)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))\$.' #
# 字符串
url3='00.'
# 匹配操作
result3=re.search(pattern3,url3)
# 输出的是
print(result3) #None# 4、当然也不可以匹配4位数字和299的,因为也超出了返回了范围# 5、可以进行缩写正则表达式,搜索表达式中相同的部分进行和并,# 这里去掉了第一部分后,一位和两位合并为:([1-9]?\d) 表示为:[1-9]?可以有也可以没有:如果匹配到了1-9之间的
# 数字,则[1-9]?表示为1,如果匹配的是0-9则使用到的就是\d# pattern4 = r'(^(?:[1-9]?\d)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))\$.'# 两位和三位的第一部分合并,首先找到他俩共同的部分,也就最后一位是\d,可以将{2}改写为\d即:(?:1\d\d),我们可以将
# (?:[1-9]?\d)的前半部分与改写后第一部分的三位数进行一个或者关系,即:(?:[1-9]?|1\d\d),然后我们在将三位数的前两位,
# 即1\d和两位数的[1-9]?,让他们再二选其一,即(?:([1-9]?|1\d)\d),这里的\d是最后一位0-9,
# (?:([1-9]?|1\d)\d)先说小括号内部的表示为:要么选左边[1-9],要么选右边1\d,如果选左边的[1-9]:即为要么有一位数要么一位数没有,
# 如果说一位数都没有的话,那么就只剩下小括号外面的\d这一位数了,如果前面的[1-9]?有一位数的话,那就表示为1-9的数字,
# 那么([1-9]?)和小括号外面的\d组合为:10-99,由于(?:([1-9]?1\d)\d)中的小括号内部的[1-9]和1\d也可以进行二选一,因为有|竖线或者嘛
# 他俩的关系表示为,如果你不选前面[1-9]?的一位或者是是0位的,那么你就得选后面这个1\d的,1\d表示为:10到99,1\d与小括号外面的
# 第三位\d合起来为:100到199。那么两位和三位的就合并成功了。
# 此时,再拿二位与三位前两位合并成功的结果即:(?:([1-9]?|1\d)\d),与后面的(?:2[0-4]\d)再次合并,我们发现它俩的共同点也是最后一位的\d,
#这时,我们把|2[0-4]的内容提取出来,放到二位数合并成功的即:(1\d)这个两位数的后面,即:(?:([1-9]?|1\d|2[0-4])\d),把提取之后的2[0-4]的
# 残余部分删除,即将(?:\d)进行删除,最终的结果为,r'((?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]))'
#[1-9]?表示为:0位或者一位数的,
#1\d表示:10到19的
# 2[0-4]表示:20到24的
# 前面两位数与三位数的前两位合并即(?:([1-9]?|1\d|2[0-4])\d)的小括号外面,只剩下最后一个\d为:0-9的
# 只有最后一个(?:25[0-5])即255这个是单独特别的,#(?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]) 这些是一个整体内容,但是里面又有很多的或者关系,如果你选择第一层竖线的后面,也就是(?:25[0-5]),表示为250-255
# 如果你选择第一层的竖线的前面,那就表示1位数字,2位数字,3位数字的10到19,3位数字的20到24.
pattern6=r'^((?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]))\.$'# 因为竖线是或者关系,所以(?:([1-9]?|1\d|2[0-4])\d)与(?:25[0-5]))是或者关系,所以即为,如果要取10到249的数字,则在(?:([1-9]?|1\d|2[0-4])\d)中取。
# 如果要取:250到255的数字即可以在(?:25[0-5])中取,两者选一即可!
# 100:取1\d中的:10,取\d中的0,即可,
# 字符串
url6='255.'
# 匹配操作
result6=re.search(pattern6,url6)
# 经过不懈的努力,获取成功,但是获取的范围一定不能超过255,否则报错
print(result6) #<re.Match object; span=(0, 4), match='255.'># 因为我们现在只匹配了一组255的数据,所以我们还要对其他几组数据进行匹配
#由于前三组的数字后面都带的点(.),而最后面的一组数字没有点,所以我们可以把前三组的数字,生成三份,后一组的数字,单独生成
# 即:把一组数字的正则表达式当做一个整体进行匹配3份
#匹配正则表达式
pattern7=r'^(((?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]))\.){3}((?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]))$'
url7='198.152.136.111'
# 匹配操作
result7=re.search(pattern7,url7)
# 经过不懈的努力,获取成功,但是获取每组数字的范围一定不能超过255,否则报错
print(result7) #<re.Match object; span=(0, 15), match='198.152.136.111'># 可以写为一个类
class IP(object):def __init__(self,ip):self.ip  = ipself.run()def run(self):pattern7 = r'^(((?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]))\.){3}((?:([1-9]?|1\d|2[0-4])\d)|(?:25[0-5]))$'url7 = self.ip# 匹配操作result7 = re.search(pattern7, url7)# 经过不懈的努力,获取成功,但是获取每组数字的范围一定不能超过255,否则报错print(result7) #<re.Match object; span=(0, 10), match='123.45.8.0'>
if __name__ == '__main__':ip=input('请输入你的ip地址')ip_dress = IP(ip)

注意获取时:只能以10开头

因为竖线是或者关系,所以正则表达式(?:([1-9]?|1\d|2[0-4])\d)与(?:25[0-5]))是或者关系,所以即为,如果要取10到249的数字,则在(?:([1-9]?|1\d|2[0-4])\d)中取。
如果要取:250到255的数字即可以在(?:25[0-5])中取,两者选一即可!

3、电话号码的匹配

import re
# 3、电话号码的匹配
#a、设定规则(纯数字:11位数字。第2,3个号码有限制)
#b、书写一些符合规则的实例
#c、书写正则
# d、验证正则
'''
13012345678
13112345678
'''# 正则表达式
# url8='"^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$"'# 进行手机号码的匹配,首先我们可以确定手机号码的后八位肯定是数字,所以我们可以先来个\d{8}# pattern8=r'13\d|147\d|15\d|17\d|19\d|176\d{8}' # 因为这里的1比较多所以我们可以把他们给提取出来
# pattern8=r'1(47\d|5\d|7\d|8\d|9\d)\d{8}' # 将它们在进行在压缩,把里面的\d都拿出来
pattern8=r'1(47|[35789])\d{8}' #把特殊的两位数的放在一块,把可以从1开头的放到[]中括号中,它们即1(47|[35789])47和[35789]的中间,
# 使用了|竖线,或者的意思# 匹配正则字符串,匹配成功
url8='15123456781'
# 匹配操作
result8 = re.search(pattern8,url8)
# 输出结果
print(result8) #<re.Match object; span=(0, 10), match='1512345678'>

4、身份证号码的匹配

import re
# 4、身份证号码的匹配# a、设定为18位的数字和字母x组成;x只能加到最后一位
#b、书写一些符合规则的实例'''
前六位  中间八位数  后面三位数    后面一位数可能是数字,也可能是字母
110345  19990901    693              3
地址    出生日期   顺序码            校验码
120234   1990912    321               x
'''
# c、书写正则
# 首先我们可以匹配地址:r'\d{6} ',因为它是六位数字
# 写顺序码的正则:因为这里是固定三位的,所以:\d{3}
# 出生年月:按实际情况来看,因为有可能有18xx年的,19xx年的,20xx年的,(18|19|[2-9]\d)\d{2}
# 开始写月份的数据:因为一年共有12个月,所以如果是以0开头的话则为01-09,因为不可能有00月啊0([1-9]),而如果是以1开头的的话只能是10-12了,所以可以表示为:(0[1-9])|1[0-2]),
# 按照日子进行分的数据:如果以1或者2开头的话,就可以写为:从10-29:([12]\d),如果是以3开头的话只有:30和31了可以写为(3[01]):他们两之间使用竖线或者关系的,([12]\d|(3[01]))
# 校验码:可以是数字也可以是x,它俩之间必须二选其一,即:(\d|x)pattern9 = r'(?#这里是前6位)\d{6}(?#这里是年份从18开始)(18|19|[2-9]\d)\d{2}(?#这里是月份)(0[1-9]|1[0-2])(?#这里是日子)([0-9]|[12]\d|3[01])\d{3}(\d|x)'# 匹配正则字符串,匹配成功
url9='110345209912251233'
# 匹配操作
result9 = re.search(pattern9, url9)
# 输出结果
print(result9) #<re.Match object; span=(0, 18), match='110345209912251233'>
print(result9.groups()) # 可以将模式单元的年月日存储起来  #('20', '12', '2', '3')

re模块:正则表达式专用模块,提供正则相关的操作方法

因为正则表达式本质是字符串,单独使用是没有意义的,正则表达式需要配合相关的函数和方法使用
正则表达式使用的四个步骤
1、书写正则表达式 pattern=r’\d+’
2、正则匹配的字符串 url = ‘abcdefg’
3、匹配操作 result = re.search(pattern
4、输出结果 print(result)

正则表达式匹配过程图


学习正则表达式相关的操作方法时注意以下几点:除了compile方法之外所有说到的方法,他们都会有两种不同的操作方法,我会先说明第一种的匹配操作格式,再说明第二种匹配操作。只要正则表达式方就是第一种,正则表达式对象方法就是第二种;

1、compile()方法:

格式:re.compile(pattern, flags=0):
格式和参数的意思:re.compile(正则表达式,模式修正符)
1、编译正则表达式获取正则表达式对象,
2、可以循环利用,提高程序效率,因为我们前面写的正则表达式都是写一个用一个,比如pattern1,pattern2了,但是使用了compile方法之后,它可以将正则表达式变为正则表达式对象,可以循环的调用它,很方便
书写格式:re.compile(正则字符串,模式修正符)注意:它是专门把正则表达式的字符串变为正则表达式对象,它只有这两个参数,模式修正符是可选参数
返回值:输出的是正则表达式的对象

# compile方法
import re
#1、ompile方法,compile可以把正则表达式编译为正则表达式对象,# 格式:re.compile(正则表达式,模式修正符),它只有这两个参数。
# pattern在未被compile方法调用之前只是个字符串
pattern = r'\d{13}' # 最多匹配13位数字
# 请看类型
# print(pattern,type(pattern)) # \d{13} <class 'str'># 把pattern通过compile方法变为具有正则方法的对象,是对象pattern_obj = re.compile(pattern,re.I)
#pattern_obj是正则表达式对象类型,所以返回的结果只会是正则表达式,模式修正符是可选参数
print(pattern_obj,type(pattern_obj)) # re.compile('\\d{13}', re.IGNORECASE) <class 're.Pattern'> # re.Pattern是正则表达式类的意思# 把pattern变为具有正则方法的对象
pattern2 = r'\d+'
url2 ='123456das'
# 上面的正则表达式对象也可以在这里使用,再也不用我们用一个写一个正则表达式了
print(pattern_obj)

2、escape()对字符串进行转义处理

仅仅进行转义处理(仅仅处理非数字和字母的字符串)
比如下面的空格将它们进行了转义
它只有一种方法的传递参数
格式:re.escape(pattern)
格式和参数的意思:re.escape(字符串)
结果:返回被转义后的字符串形式

import re
#escape()对字符串进行转义处理
s = 'how old are you ? i am 21'
result = re.escape(s)
# 仅仅进行转义处理(仅仅处理非数字和字母的字符串)
print(result) #how\ old\ are\ you\ \?\ i\ am\ 21

3、findall()正则表达式方法:

对字符串进行正则匹配,获取所有的匹配的内容结果,这里它返回的可不是一个match对象,它会直接返回结果到列表中但是,还没有被取出来,下面会涉及到取出数据的方法,记住它的特点,是可以返回所有的符合正则表达式的结果,而不是只返回一个结果,它返回的是一个列表,
格式:re.findall(pattern, string, flags=0)
格式和参数的意思:re.findall(正则表达式,匹配字符串,模式修正符),模式修正符是可选参数
结果:返回一个存放所以结果的列表

import re
# 对字符串进行正则匹配,获取所有的匹配结果
# 格式:findall(正则表达式,匹配字符串,模式修正符)
# 返回列表
pattern = r'www'url = 'www.baidu.www.WWWWcom'result = re.findall(pattern,url,re.I)print(result) #  ['www', 'www', 'WWW']

4、finditer()正则表达式方法:

对字符串进行正则匹配,获取所有匹配的结果对象,对象是一个可迭代对象,注意:这里它返回的只是结果对象,并不是结果。
格式参数:re.finditer(pattern, string, flags=0)
格式和参数的意思:re.finditer(正则表达式,匹配字符串,模式修正符)模式修正符是可选参数
结果:注意:因为它包含所有匹配结果的可迭代对象,强调一下这里匹配返回的结果是一个可迭代对象而不是迭代器对象,一定要分清楚,如果要获取结果则要使用迭代器,或成器来取出里面的结果对象,比如石油for循环,请看实例:

import re
pattern= r'baidu'url = 'baidu BAIDU Baidu'
#finditer方法唯一和findall不同的是,finditer方法返回的是一个可迭代对象,谨记,这里是可迭代对象,而不是迭代器对象,不要搞混了
result = re.finditer(pattern,url,re.I)
print(result)# 因为返回的是可迭代对象,所以我们可以对它进行遍历
for i in result:print(i)
# 它输出的是包含所以所有匹配的match结果对象,包含下标span
# <re.Match object; span=(0, 5), match='baidu'>
# <re.Match object; span=(6, 11), match='BAIDU'>
# <re.Match object; span=(12, 17), match='Baidu'>

5、match()方法正则表达式方法:

格式:re.match(pattern, string, flags=0):
格式和参数意思:re.match(正则表达式,匹配的字符串,模式修正符)模式修正符参数是可选参数。
使用match方法来查找字符串,前面我们使用的过的search方法和finditer方法输出的结果都是match对象,match方法当然也返回match对象啦,这里记住match方法只匹配一次,它是从头开始匹配,不管匹配是否成功,都是只匹配一次,如果成功则返回结果,如果不成功则返回None,
下面请看实例:
如果开头的字符串不符合正则表达式的话,就直接返回None不再往后继续查找,如果字符第一个字符符合匹配的正则表达式的话,就直接返回结果,不再往后继续查找,
结果:返回结果为match对象

import re
url1 = 'one12love34like56lala'
# 因为match方只匹配一次,从头开始匹配,如果开头都不符合的话,那就返回None喽,比如这里如果使用match方法匹配不到结果
# 因为这里的正则表达式的要求是获取一个或者多个数字,而字符串中首个字符是字母,而我们使用的是match方法,所以直接将match
# 方法的路堵死,只能返回None了
result1 = re.match(r'\d+',url1)
print(result1) #None# 这次第一个字符符合正则表达式,符合结果的话也是匹配一次,直接返回匹配的结果
url2 = '12love34like56lala'result2 = re.match(r'\d+',url2)
print(result2) #<re.Match object; span=(0, 2), match='12'>url3 = '12789love34like56lala'
# 限制匹配2个数字
result3 = re.match(r'\d{2}',url3)
print(result3) #<re.Match object; span=(0, 2), match='12'>

6、search()正则表达式方法

前面的例子基本上用的都是search方法,它比match方更先进,虽然它也是只匹配一次,但它会是从任意位置开始查找,即便第一个字符串中的字符不匹配,也会继续往后查找,而不会在开头不符合的情况下就被堵死,只要匹配到结果后,就返回一个结果,停止匹配操作,不像match方法是从头开始查找,只要第一个字符不符合就返回None,
格式:re.search(pattern, string, flags=0)
格式和参数意思:re.search(正则表达式,字符串,模式修正符),模式修正符是可选参数
结果:返回结果为一个match对象

import re#因为search方法也是匹配一次,如果匹配到结果那就返回结果,如果没有匹配到也返回,但是返回None# search方法是从任意位置匹配的,只匹配一次,哪怕要匹配的字符串中的第一个字符不符合正则表达式,那也会继续往下查找
# 直到返回结果
url = '123das22das444'
# 获取1个或者更多的数字,第一个字符符合正则表达式
result = re.search(r'\d+',url,re.I)print(result) #<re.Match object; span=(0, 3), match='123'>url2 = '123das22das44DASD4'
# 获取a-z范围字母 虽然这里的字符串首个字符串它不符合正则,但是也可以匹配的到,因为这是search方法呀
result2 = re.search(r'[a-z]',url2,re.I)print(result2) #<re.Match object; span=(3, 4), match='d'>ur3 = 'love123das22das444'
# 获取1个或者更多的任何字符,这几个大小写的正则表达式都是一个意思,匹配任何字符
result3 = re.search(r'[\s\S]+',ur3)print(result3) #<re.Match object; span=(0, 18), match='love123das22das444'>url4 = '123das22das444'
# 获取1个或者更多的任何字符
result4 = re.search(r'[\w\W]+',url4)print(result4) # <<re.Match object; span=(0, 14), match='123das22das444'>url5 = '123das\*-+das4'
# 获取1个或者更多的任何字符
result5 = re.search(r'[\w\W]+',url5)print(result5) #<re.Match object; span=(0, 14), match='123das\\*-+das4'>

7、split切割字符串方法

格式re.split(pattern, string, maxsplit=0, flags=0)
格式和参数意思:re.split(正则表达式,需要切割的字符串,切割最大次数,模式修正符),后两个是可选参数
使用正则表达式来切割字符串,以正则表达式中的内容作为分割符,则正则表示中是什么,就以什么作为分割符,这里说的以什么作为分割符的意思是,在匹配时只要遇到正则表达式中的内容,则它就会作为分割的[,]将其他的字符分割开来,而输出的结果则是列表类型,每个字符之间使用逗号[,]来分割

import re
# # 我要想把下面的字符串都分割开来该如何做呢,我们可以使用,split方法用来切割字符串,
# 格式:re.split(正则表达式,需要切割的字符串,切割最大次数)
# 这里我们设置的是以数字来作为分割符来分割字符串,也就是说匹配的字符串中,只要是数字就会作为分割符,
# 这里没有限制最大次数,
url = '耶1我2和3我4的5祖6国7很8厉9害'
result =re.split(r'\d+',url)print(result) # ['耶', '我', '和', '我', '的', '祖', '国', '很', '厉', '害']# 我们来使用一下分割最大次数的参数url2 = '耶1我2和3我4的5祖6国7很8厉9害'
result2 =re.split(r'\d+',url2,5) # 在这里我们限制了分割的次数只能是五次
# 可以发现除了前面的5个汉字,其他的都没有被分割
print(result2) # ['耶', '我', '和', '我', '的', '祖6国7很8厉9害']

8、sub方法:正则的替换

格式和参数:sub(pattern, repl, string, count=0, flags=0)
格式和参数代表的意思
re.sub(正则表达式,替换的字符串,需要匹配的字符串,限制替换的最大次数,模式修正符)如果不给最大次数传递参数则默认为无限制,
后两个是可选参数
结果:匹配字符串被替换之后的字符串

import re
# 1、正则的替换:sub方法
# 方法参数:sub(pattern, repl, string, count=0, flags=0)
# 参数代表的意思
# re.sub(正则表达式,替换的字符串,需要匹配的字符串,限制替换的最大次数,模式修正符)如果不给最大次数传递参数则默认为无限制,
# 后两个是可选参数url1 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'# 我们要将字符串中的蜡笔小新全部替换成为,野原新之助pattern = r'蜡笔小新'replace_s = '野原新之助'result = re.sub(pattern,replace_s,url1)
# 全部替换成功
print(result) #野原新之助的爸爸是野原广志,野原新之助的妈妈是野原美伢,野原新之助的妹妹是野原葵,野原新之助的小伙伴是我们# 2、限制替换的次数url12 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'# 我们要将字符串中的蜡笔小新全部替换成为,野原新之助pattern2 = r'蜡笔小新'replace_d = '野原新之助'result2 = re.sub(pattern2,replace_d,url12,2)
# 这次可以发现只替换了2出的蜡笔小新成
print(result2) #野原新之助的爸爸是野原广志,野原新之助的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们#3、我们要将字符串中的蜡笔小新全部替换成为,野原新之助
url13 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'pattern3 = r'[\s\S]+'replace_d3 = '879879798'
# 将所有的字符串替换为数字
result3 = re.sub(pattern3,replace_d3,url13,)
# 字符串全部成为了数字
print(result3) #879879798# 4、sub方法也可以接收函数url14 = 'h e l l o w o r l d '
url15 = '*'
pattern4 = r'\w+'
result4 = re.sub(pattern4,url15,url14,10)
# 如果匹配的字符串中没有空格到的话,替换的字符串将把整个字符串替换为,替换的字符串即:*
# 如果有空格的话则会把每个字符串都替换为,替换的字符串*
print(result4) # * * * * * * * * * *

9、subn()方法正则替换

格式:re.subn(正则表达式,要替换的字符串,要匹配的字符串,替换次数,模式修正符)
这里注意一定要将,要替换的字符串和要匹配的字符串分清楚,要替换的字符串指的是:把要匹配中的字符串,如果符合正则表达式则把这些字符都替换为,要替换的字符串。
结果:由替换之后的字符串和替换次数组成的元组!它比sub方法的输出结果,多了个显示次数的结果。

import reurl1 = r'abced79465fg'
url12 = '我是大帅哥'
# subn正则替换,
# 格式:re.sybn(正则表达式,要替换的字符串,要匹配的字符串,替换次数)
# 将url1中的数字全部替换为url2
result = re.subn(r'\d+',url12,url1,5)
# 结果:有替换之后的字符串和替换次数组成的元组!
print(result) #返回的元组 #('abced我是大帅哥fg', 1)url3 = r'abced79465fg'
url13 = '我是大帅哥'
# subn正则替换,
# 格式:re.sybn(正则表达式,要替换的字符串,要匹配的字符串,替换次数)
# 将rul3中的字母全部替换为url3中的文字
result3 = re.subn(r'[\w+]',url13,url3,5)
# 结果:有替换之后的字符串和替换次数组成的元组!
print(result3) #('我是大帅哥我是大帅哥我是大帅哥我是大帅哥我是大帅哥79465fg', 5)  # 注意,它这里的输出结果可以显示被替换的次数

第二种,正则对象的方法(协助compile方法获取)

我们前面所说的几种re模块的操作方法都是,以这样的格式来输出结果的
匹配操作一:re.模块(正则表达式,要匹配的字符串)结果对象
意思就是说,使用re模块,并把正则表达式和字符串的一个混合,然后得到一个结果对象,我们前面使用的就是匹配操作一的方法
比如在下面的方法中我使用pattern这个变来引用re.compile这个方法,
pattern = re.compile(‘正则表达式’)
所以pattern就代表的是正则表达式的对象
下面的使用方法都是这样的比如拿findall方法来说:
pattern.findall(要匹配的字符串,模式修正符)

1、findall()正则表达式对象方法:

findall()正则表达式对象方法:使用正则表达式对象对指定的字符串进行匹配出操作,获取所有匹配结果组成的列表
配合compile方法使用时
格式和参数1:re.compile().findall(string,pos,endpos)
格式和参数意思1:re.compile.findall方法(要匹配的字符串,起始位置,结束位置)
也可以这样写:
正则表达式:pattern = re.compile(‘正则表达式’, 模式修正符)
格式2:pattern.findall(要匹配的字符串, ,起始位置,结束位置)
结果:返回一个所有结果的列表

一般我们是先使用re.compile创建一个正则表达式对象,然后和findall方法一起使用,
比如:

# \d匹配数字,将数字单个分开
# 创建一个正则表达式对象
pattern1 = re.compile('\d')
result1 = pattern1.findall('hello 123 456 789')
print(result1) # ['1','2','3','4','5','6','7','8','9'

这里注意:这样的方法也可以直接把compile方法和findall放在一块使用,看自己习惯了,因为都是表达了一个意思
第一个测试方法使用到了方法中的所有的参数,
我们可以发现在这里与前面的与众不同的是,findall方法的括号中的第一个参数不再是正则表达式,也不能调用模式修正符,但是compile方法可以调用模式修正符

# 导入re正则包
import re
# 这样的方法也可以直接把compile方法和findall放在一块使用,看自己习惯了,因为都是表达了一个意思
# 第一个测试方法使用到了方法中的所有的参数
url='abHFKSc12346789'
# 我们可以发现在这里与前面的与众不同的是,findall方法的括号中的第一个参数不再是正则表达式,也不能调用模式修正符,
# 但是re.compile方法可以调用呀所有执行结果和前面学习的第一种操作还是一样的。
result1 = re.compile(r'        \w+',re.X).findall(url,1,5)
print(result1) #['bHFK']# \d只匹配数字,将数字单个分开
pattern1 = re.compile('\d')
result1 = pattern1.findall('hello 123 456 789')
print(result1) # ['1', '2', '3', '4', '5', '6', '7', '8', '9']# 2、 \d+ 可以匹配一个或者多个数字,如果是多个数字,则必须连续在一起,
pattern2 = re.compile('\d+')
result2 = pattern2.findall('hell 123 456 zsjd78dd')
print(result2) #['123', '456', '78']# 3、 \d{3,} 只匹配数字3个或者多个数字,必须连续在一起,也就是只匹配3个以上的连续的数字
pattern3 = re.compile('\d{3,}')
result3 = pattern3.findall('hellow 12313 55 jd88pp $%#&*^')
print(result3) #['12313']# 4、 \d{3} 只匹配3个连续在一起的数字字符
pattern4 = re.compile('\d{3}')
result4 = pattern4.findall('hellow 123 456 88 das45da56da4d146')
print(result4) # ['123', '456', '146']# 5、 \d{1,2} 可以匹配一个数字字符,也可以匹配两个数字字符,以两个数字字符优先匹配
pattern5 =re.compile('\d{1,2}')
result5 = pattern5.findall('hellow 123 789 dad78da4 da5da2')
print(result5) # ['12', '3', '78', '9', '78', '4', '5', '2']# 6、re.I 表示忽略大小写,就是说即便这个字符串中有大写和小写,我也不管,将大小的字符串写都匹配出来,
# [a-z]{5}匹配a-z的字母,匹配只要是5个字符的无论大小写,并且字符是连续在一起的,
pattern6 = re.compile('[a-z]{5}',re.I)
result6 =pattern6.findall('lovelove likelike 123456 das45ddasd8 das66')
print(result6) # ['lovel', 'likel', 'ddasd']# 7、 \w+匹配数字、字母、下划线,一个或者多个字符,多个则无限制
pattern7 = re.compile('\w+')
result7 = pattern7.findall('$#%^_____dasd 8979 da 4564;;;<><?')
print(result7) # ['_____dasd', '8979', 'da', '4564']# 8、 \W+ 匹配不是下划线、字母、数字、的字符
pattern8 = re.compile('\W+')
result8 = pattern8.findall('$#%^_____dasd 8979 da 4564;;;<><?')
print(result8) # ['$#%^', ' ', ' ', ' ', ';;;<><?']# 9、[\w\W]+ 可以匹配所有的字符,单个或多个字符
pattern9 = re.compile('[\w\W]+')
result9 = pattern9.findall('123 abc /// ??? <><>  )_+*&^%$#@!~ MONKEY')
print(result9) # ['123 abc /// ??? <><>  )_+*&^%$#@!~ MONKEY']# 10、[abc]+ 匹配a或者b或者c单个或者多个字符,多个字符则连在一起
pattern10 = re.compile('[abc]+')
result10 = pattern10.findall('aaa bbb ccc rdka789 132 ;;;,,')
print(result10) # ['aaa', 'bbb', 'ccc', 'a']# 11、 [~abc|123]+ 匹配只有abc或者123的单个字符
pattern11 = re.compile('[~abc|123]')
result11 = pattern11.findall('dasd____ 123 abc .,,dsa!##$$%^&%^*^')
print(result11) # ['a', '1', '2', '3', 'a', 'b', 'c', 'a']# 12、 .*表示匹配任意字符,除了换行符
pattern12 = re.compile('.*')
result12 =pattern12.findall('dsadas~@!#$@%#$^%&^&(*()_)+__132 789 dasd ')
print(result12) # ['dsadas~@!#$@%#$^%&^&(*()_)+__132 789 dasd ', '']# 13、 findall函数里面的后两个参数,指的是匹配字符的起始位置和结束位置
pattern13 = re.compile('\d+')
# 只匹配0-10长度大小的数字字符并且是连续在一起的
result13 = pattern13.findall('dasd 12313 654 6 8 4 1 4 88888',0,10)

2、finditer()正则表达式对象方法:

格式和参数1:re.compile().finditer(string,pos,endpos)
格式和参数的意思1:re.compile().finditer(要匹配的字符串,开始匹配位置,结束匹配位置)
finditer方法的行为跟findall的行为类似,也是搜索整个字符串,获取所有匹配的结果,但它会返回一个顺序访问每一个匹配结果(Match对象)的迭代器,通过for循环或者生成器,可以将它的值进行遍历出来。
也可以这样写
正则表达式对象:pattern = re.compile(‘正则表达式’,模式修正符)
格式2:pattern.finditer(要匹配的字符串, 开始匹配位置,结束匹配位置)
结果:返回一个可迭代对象,强调:这里获取的结果是可迭代对象,而不是迭代器对象
后面会说到如何取出它的结果

import re
pattern= r'baidu'url = 'baidu BAIDU Baidu'
#finditer方法唯一和findall不同的是,finditer方法返回的是一个可迭代对象
#
result = re.finditer(pattern,url,re.I)
print(result)# 因为返回的是可迭代对象,所以我们可以对它进行遍历
for i in result:print(i)
# 它输出的是包含所以所有匹配的match结果对象,包含下标# <re.Match object; span=(0, 5), match='baidu'>
# <re.Match object; span=(6, 11), match='BAIDU'>
# <re.Match object; span=(12, 17), match='Baidu'>

3、matc()h正则表达式对象方法:

match方法用于查找字符串的头部(也可以指定起始位置和结束位置),他只是一次匹配,只要找到了一个匹配的结果就会返回,而不是查找所有匹配的结果。它的一般使用形式如下:
格式和参数1:re.compile.match(string,pos,endpos)
格式和参数的意思1:re.compile.match(要匹配的字符串,初始位置,结束位置)
也可以这样写:
正则表达式对象:pattern = re.compile(‘正则表达式’,模式修正符)
格式2:pattern.match(要匹配的字符串, 开始匹配位置,结束匹配位置)
其中,string是待匹配的字符串,pos和endpos是可选参数,指定字符串的起始和终点位置,默认值分别是0和len(字符串长度)。因此,当你不指定pos和endpos时,match方法匹配字符串的头部。
结果:返回一个Match对象

import re
pattern =re.compile(r'([a-z]+)([a-z]+)',re.I) # re.I表示忽略大小写
m = pattern.match('hello world well welcome')
# 匹配成功
print(m) # <re.Match object; span=(0, 5), match='hello'>
#这里注意:一定要记得match方法的特征,只要匹配的字符串第一个字符不合适,则返回None
patter = re.compile(r'\d+') # 用于匹配至少一个数字m = patter.match('oner12 adad34formd888',1,20) # 查找头部,没有匹配
print(m) #None# 2、从'e'的位置开始匹配,没有匹配
m2 =  patter.match('one12two3478like88',2,10)
print(m2) ## 3、从'1'的位置开始匹配,正好匹配到返回一个Mathc对象
m3 = patter.match('abc12two3488dad',3,10)
print(m3) #<re.Match object; span=(3, 5), match='12'>

4、search()正则表达式对象方法:

search方法用于查找字符串的任何位置,它也是一次匹配,只要找到一个匹配的结果就返回,而不是查找所有的匹配的结果,这里注意下:它可以从任意的位置查找字符,他和match方法不同,match方法时从匹配字符串的开头位置开始查找,只要开头的第一个字符都不符合正则表达式的话,match方法就无法在继续向下查找,即返回一个None值,而search方法即便第一个字符不符合正则表达式,它也会继续往下查找,如果有结果则返回,如果没有则返回None,只匹配一次,值它的一般使用形式如下:
格式和参数1:search(string[,pos[,endpos]])
格式和参数的意思1:re.comile.search(要匹配的字符串,设置查询的开始位置,设置查询的结束位置)
也可以这样写
正则表达式对象:pattern = re.compile(‘正则表达式’,模式修正符)
格式2:pattern.search(要匹配的字符串, 开始匹配位置,结束匹配位置)
其中,string是待匹配的字符串,pos和endpos是可选的参数,指定字符串的起始和终点位置,默认值分别是0和len(字符串长度)。
结果:当匹配成功时,返回一个Match对象,如果没有匹配成功,则返回None。

import repattern = re.compile('\d+') # 匹配一个或多个数字
# 这里如果使用match方法则不匹配
m = pattern.search('one12love34like56lala') #
print(m) #<re.Match object; span=(3, 5), match='12'>m2 = pattern.search('one12two34three56',10,30) # 指定字符串的区间
print(m2) #<re.Match object; span=(15, 17), match='56'># 将正则表达式编译成pattern对象
pattern2 = re.compile(r'\d+')
# 使用search()查找匹配的子串,不存在匹配的子串时返回None
# 这里使用match()方法无法匹配
m3 = pattern2.search('hello 123456 789888')
print(m3) # <re.Match object; span=(6, 12), match='123456'>

5、spilt()正则表达式对象方法:

格式和参数1:re.compile.split(string,maxsplit):
格式和参数的意思1:正则表达式对象.split方法(要切割的字符串,限制最大次数)
maxsplit用于指定最大分割次数,不指定将全部分割
也可以这样写:
正则表达式对象:pattern = re.compile(‘正则表达式’,模式修正符)
格式2:pattern.split(要匹配的字符串, 限制最大次数)
结果返回的是:它将字符串切割后,字符串成为单个的子串,子串以列表的形式返回结果

import re
# 1、未限制切割次数
# 正则表达式对象,
pattern = re.compile(r'\d+')
# 打印它的类型,正则表达式类型
print(pattern,type(pattern)) #re.compile('\\d+', re.IGNORECASE) <class 're.Pattern'>
# 匹配的字符串
url1 = '10世9贫,凑得8两7钱6分5毫4厘,况且3心2意,1等下流'# 匹配操作
result1  = pattern.split(url1)
# 让字符串中的只要是数字的字符全都成为切割的字符,
print(result1) #['', '世', '贫,凑得', '两', '钱', '分', '毫', '厘,况且', '心', '意,', '等下流']# 2、限制切割的次数
# 正则表达式对象,
pattern2 = re.compile(r'\d+')
# 打印它的类型,正则表达式类型
print(pattern2,type(pattern2)) #re.compile('\\d+', re.IGNORECASE) <class 're.Pattern'>
# 匹配的字符串
url1 = '10世9贫,凑得8两7钱6分5毫4厘,况且3心2意,1等下流'# 匹配操作,设置匹配的次数为3次
result1  = pattern.split(url1,3)
# 让字符串中的只要是数字的字符全都成为切割的字符,限制它只切割3次
print(result1) #['', '世', '贫,凑得', '两7钱6分5毫4厘,况且3心2意,1等下流']

6、sub()正则表达式方法:正则替换字符串

格式1:re.compile.sub(repl,string,count)
格式和参数1的意思:正则表达式对象.sub方法(要替换的字符串,要匹配的字符串,替换的最大次数)
也可以这样写
正则表达式对象:pattern = re.compile(‘正则表达式’,模式修正符)
格式2:pattern.sub(要替换的字符串,要匹配的字符串, 限制替换最大次数)
如果不给限制的最大次数传递参数则默认为全部替换。
结果:返回一个被替换后的字符串

import re
# 正则表达式匹配字符串中的'的'这个字符
pattern = re.compile(r'的')# pzttern.sub(替换的字符串,需要匹配的字符串,限制替换的最大次数),如果不给最大次数传递参数则默认为无限制,
# 最后一个是可选参数url1 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'# 我们要将字符串中的,这个'的'字替换为日文的'の'
result = pattern.sub('の',url1)
# 我们可以发现已经全部替换为“の”
print(result) #蜡笔小新の爸爸是野原广志,蜡笔小新の妈妈是野原美伢,蜡笔小新の妹妹是野原葵,蜡笔小新の小伙伴是我们#2、限制最大次数
url1 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'# 我们要将字符串中的,这个'的'字替换为日文的'の',并且只允许它替换2次
result = pattern.sub('の',url1,2)
#我们可以发现只替换了字符串前面的两个'的'字
print(result) #蜡笔小新の爸爸是野原广志,蜡笔小新の妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们

7、subn正则表达式对象方法:

格式1:re.compile.sub(repl,string,count)
格式和参数1的意思:正则表达式对象.sunb方法(要替换的字符串,要匹配的字符串,替换的最大次数)
也可以这样写
正则表达式对象:pattern = re.compile(‘正则表达式’,模式修正符)
格式2:pattern.subn(要替换的字符串,要匹配的字符串, 限制替换最大次数)
如果不给限制的最大次数传递参数则默认为全部替换。
结果:返回一个被替换后的字符串,以元组形式展现,并且在元组的最后可以看到被替换的次数,即返回字符串和次数组成的元组。

import re# subn方法
# 正则表达式,将字符串中的,'的'这个字匹配出来
pattern= re.compile(r'的')
# 查看pattern的类型
print(pattern,type(pattern))
# 要匹配的字符串
url1 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'
# 将正表达式匹配出来的'的'这个字将它替换为'の'这个字
result1 = pattern.subn('の',url1)
# 这里我们可以发现,其实它和sub方法差不多,就是多了个可以让我们查看我们需要替换的次数,在字符串中替换了多少次
print(result1) #('蜡笔小新の爸爸是野原广志,蜡笔小新の妈妈是野原美伢,蜡笔小新の妹妹是野原葵,蜡笔小新の小伙伴是我们', 4)# 限制替换的次数
url2 = '蜡笔小新的爸爸是野原广志,蜡笔小新的妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们'
# 将正表达式匹配出来的'的'这个字将它替换为'の'这个字,并设置一个最大的替换次数为:2次
result2 = pattern.subn('の',url2,2)
# 这里我们可以发现,'的'这个字符在字符串中被替换了2次,并有记录替换了2次
print(result2) #(('蜡笔小新の爸爸是野原广志,蜡笔小新の妈妈是野原美伢,蜡笔小新的妹妹是野原葵,蜡笔小新的小伙伴是我们', 2)

正则表达式对象方法提供的几个属性:

1、flags()属性:


flags属性:获取当前正则对象的模式修正符,(注意这里只说的是正则对象即,re.compile的模式修正符),而没有说是上面正则模块方法的模式修正符

import re# flags:获取当前正则对象的模式修正符# 1、flags
fl = re.compile(r'\d+',re.I)
# 这里可以发现其实每个模式修正符都有它的编号
print(fl.flags) # 34#也可以这样写,可以写一个也可以写两个
f2 = re.compile(r'(?s)\d+')print(f2.flags) # 336

通过案例可以发现我们把单独的每个flags属性打印出来的时候,他们每个模式修正符,都代表的一个编号,其实吧这东西用处不是很大。

2、pattern()属性:

import re
# 这时候可能会有点疑惑了,re.compile方法中写的不就是正则表达式吗?为啥这里还要获取正则表达式的字符串格式呢?,
# 因为我们现在是一个正则对象,如果这个正则对象是别人给你的,你可能会不知道它是个啥意思,所以我们可以将它打印出来看看pa = re.compile(r'(.*?)|([a-z])')
# 这里可以发现已经打印出了正则表达式的内容
print(pa.pattern) #(.*?)|([a-z])

3、groups属性:

获取模式单元的个数

import re
# groups属性:获取模式单元的个数
# 1、这里我们可以发现有四个模式单元
pa1 = re.compile(r'(.*?)([a-z])(\d)(\s\S)')
# 这里可以发现也确实已经打印出了四个模式单元的个数
print(pa1.groups) # 4# 2、如果是自定义模式单元,也就是字典模式单元,也会获取到
pa2 = re.compile(r'(.*?)([a-z])(?P<b>\d)(\s\S)')
# 这里可以发现即便有字典模式单元也会被打印出来
print(pa2.groups) # 4

4、groupindex属性:

import re# 如果模式单元中有,自定义模式的模式单元,它会以字典的格式输出,不会打印模式单元的个数
pa2 = re.compile(r'(.*?)([a-z])(?P<b>\d)(?P<a>\s\S)')
# 这里可以发现即便有字典模式单元也会以字典的个数被打印出来
print(pa2.groupindex) # {'b': 3, 'a': 4}

group,span,start,end属性:

这个属性是用来获取那些,返回的结果都是match对象的方法,这么说可能不太好理解。
即:比如使用search方法匹配正则表达式后,可以返回match对象的结果,而这些match对象,它只是一个结果的对象,也就是相当于一个变量引用这这个结果,但是并没有将它们的结果取出来,因此我们可以使用group,groups属性将这些结果对象取出来

注意:以下几个方法都可以使用group属性将它们的结果取出来
而我们都知道正则的使用有两种方法,一个是正则表达式的使用方法,一个是正则表达式对象的使用方法,下面我都会一一说明他们之间属性的使用方法

1、match()正则表达式方法group,span,start,end属性的使用

# 正则表达式,match方法的group,groups,span,start,end属性
# 在这里写正则表达式时两个模式单元的中间即([a-z]+)的中间一定不要忘了那个空格,否则匹配有误
pareent = re.compile(r'([a-z]+) ([a-z]+)')
result1 = re.match(pareent,'hello world')
# 1、返回匹配成功的整个字符串
# 注意这里的group和group(0)的意思是一样的
print(result1.group())# hello world
print(result1.group(0)) # hello world
# 2、返回第一个模式单元匹配成功的子串
print(result1.group(1)) # hello
# 3、返回第一个模式单元匹配成功的子串的索引
print(result1.span(1)) # (0, 5)
# 4、返回第二个模式单元匹配成功的子串索引
print(result1.group(2)) # world
# 以元组的方式返回所有模式单元匹配成功的子串,相当于group(1)和group(2)
print(result1.groups()) # ('hello', 'world')
# 返回所有模式单元匹配成功的字符串开头位置的索引
print(result1.start()) # 0
# 返回所有模式单元匹配成功的字符串结束位置的索引
print(result1.end()) # 11

2、match()正则表达式对象方法group,span,start,end属性的使用

import re
# 1、
pattern =re.compile(r'([a-z]+) ([a-z]+)',re.I) # re.I表示忽略大小写
m = pattern.match('hello world')
# 匹配成功
print(m) # <re.Match object; span=(0, 11), match='hello world'># 2、m.group
# 返回匹配成功的整个子串
print(m.group(0)) # hello world# 返回匹配成功的整个子串的索引
print(m.span(0)) # (0, 11)# 返回第一个分组匹配成功的子串
print(m.group(1)) # hello# 返回第一个分组匹配成功的子串的索引
print(m.span(1)) # (0, 5)
# 返回第二个分组匹配成功的子串
print(m.group(2)) # world# 返回第二个分组匹配成功的子串的索引
print(m.span(2)) # (6, 11)# 等价于(m.gruop(1),m.group(2))
print(m.groups()) # ('hello', 'world')

3、search方法: 正则表达式方法group,span,start,end属性的使用

import re# 正则表达式,search方法的group,groups,span,start,end属性
# 在这里写正则表达式时两个模式单元的中间即([a-z]+)的中间一定不要忘了那个空格,否则匹配有误
pareent = re.compile(r'([a-z]+) ([a-z]+)')
result1 = re.search(pareent,'hello world')
# 1、返回匹配成功的整个字符串
# 注意这里的group和group(0)的意思是一样的
print(result1.group())# hello world
print(result1.group(0)) # hello world
# 2、返回第一个模式单元匹配成功的子串
print(result1.group(1)) # hello
# 3、返回第一个模式单元匹配成功的子串的索引
print(result1.span(1)) # (0, 5)
# 4、返回第二个模式单元匹配成功的子串索引
print(result1.group(2)) # world
# 以元组的方式返回所有模式单元匹配成功的子串,相当于group(1)和group(2)
print(result1.groups()) # ('hello', 'world')
# 返回所有模式单元匹配成功的字符串开头位置的索引
print(result1.start()) # 0
# 返回所有模式单元匹配成功的字符串结束位置的索引
print(result1.end()) # 11

4、search方法正则表达式对象方法group,span,start,end属性的使用

import re# 正则表达式对象,search方法的group,groups,span,start,end属性
# 在这里写正则表达式时两个模式单元的中间即([a-z]+)的中间一定不要忘了那个空格,否则匹配有误
pareent = re.compile(r'([a-z]+) ([a-z]+)')
result1 = pareent.search('hello world')
# 1、返回匹配成功的整个字符串
# 注意这里的group和group(0)的意思是一样的
print(result1.group())# hello world
print(result1.group(0)) # hello world
# 2、返回第一个模式单元匹配成功的子串
print(result1.group(1)) # hello
# 3、返回第一个模式单元匹配成功的子串的索引
print(result1.span(1)) # (0, 5)
# 4、返回第二个模式单元匹配成功的子串索引
print(result1.group(2)) # world
# 以元组的方式返回所有模式单元匹配成功的子串,相当于group(1)和group(2)
print(result1.groups()) # ('hello', 'world')
# 返回所有模式单元匹配成功的字符串开头位置的索引
print(result1.start()) # 0
# 返回所有模式单元匹配成功的字符串结束位置的索引
print(result1.end()) # 11

5、finditer正则表达式方法,roup,span,start,end属性的使用

这里注意:其实方法使用起来效果都是一样的你可以根据自己的喜好看的使用,

# finditer正则表达式方法group,groups,start,end属性的使用
pattern1 = re.compile(r'\d+')result_iter1 = re.finditer(pattern1,'hellow 13465789 888')
result_iter12 = re.finditer(pattern1,'one12love34like56')
# 可迭代对象
print(type(result_iter1)) # <class 'callable_iterator'>
print(type(result_iter12)) #<class 'callable_iterator'>print('result...')
for m1 in result_iter1: # m1是Match对象,# group获取所有匹配到的子串的内容,span获取子串的起始位置和结束位置的索引print((m1.group(),m1.span(),))# ('13465789', (7, 15))# 7   15# 获取它的起始位置和结束位置的索引print(m1.start(),m1.end())# ('888', (16, 19))# 16 19
print('result2...')
for m2 in result_iter12:# group获取所有匹配到的子串的内容,span获取子串起始位置和结束位置的索引print((m2.group(),m2.span(),))# ('12', (3, 5))# 3  5# 获取它的起始位置和结束位置的索引print(m2.start(),m2.end())# ('3', (9, 10))# 9  10

6、finditer正则表达式对象方法,roup,span,start,end属性的使用

# finditer正则表达对象式方法group,groups,start,end属性的使用
pattern1 = re.compile(r'\d+')result_iter1 = pattern1.finditer('hellow 13465789 888')
result_iter12 = pattern1.finditer('one12love34like56',0,10)
# 可迭代对象
print(type(result_iter1)) # <class 'callable_iterator'>
print(type(result_iter12)) #<class 'callable_iterator'>print('result...')
for m1 in result_iter1: # m1是Match对象,# group获取所有匹配到的子串的内容,span获取子串的起始位置和结束位置的索引print((m1.group(),m1.span(),))# ('13465789', (7, 15))# 7   15# 获取它的起始位置和结束位置的索引print(m1.start(),m1.end())# ('888', (16, 19))# 16 19
print('result2...')
for m2 in result_iter12:# group获取所有匹配到的子串的内容,span获取子串起始位置和结束位置的索引print((m2.group(),m2.span(),))# ('12', (3, 5))# 3  5# 获取它的起始位置和结束位置的索引print(m2.start(),m2.end())# ('3', (9, 10))# 9  10

search和match方法的区别

其实前面也经常提到过,但是感觉不是很清晰;

1、match方法的特点 :

import re
# match正则表达式方法,它的使用是格式为re.match(正则表达式,要匹配的字符串)
# 格式:re.match(pattern, string, flags=0):
# 格式和参数意思:re.match(正则表达式,匹配的字符串,模式修正符)模式修正符参数是可选参数。
# 这里记住match方法只匹配一次,它是从头开始匹配,不管匹配是否成功,都是只匹配一次,如果成功则返回结果,如果不成功则返回None,
# 下面请看实例:
# 如果开头的字符串不符合正则表达式的话,就直接返回None不再往后继续查找,如果字符第一个字符符合匹配的正则表达式的话,就直接返回结果,不再往后继续查找。
# 结果返回一个match对象
# 正则表达式
# 输出为None时
pattern = re.compile(r'[a-z]+')
# 要匹配的字符串
url1 = '110police'
# 匹配操作
result = re.match(pattern,url1)
# 输出结果
# print(result) #None

# 输出结果不为None时
pattern = re.compile(r'[a-z]+')
# 要匹配的字符串
url1 = 'police110'
# 匹配操作
result1 = re.match(pattern,url1)
# 输出结果
print(result1) # <re.Match object; span=(0, 6), match='police'>

2、search方法的特点 :

import re# 第一个字符为数字时
pattern2 = re.compile(r'[a-z]+')
# 要匹配的字符串
url2 = '110police'
# 匹配操作
result2 = re.search(pattern2,url2)
# 输出结果
print(result2) #<re.Match object; span=(3, 9), match='police'># 第一个字符不为数字时
pattern3 = re.compile(r'[a-z]+')
# 要匹配的字符串
url3 = 'police110'
# 匹配操作
result3 = re.search(pattern3,url3)
# 输出结果
print(result3) # <re.Match object; span=(0, 6), match='police'>

由此可以看出它们两个的区别,很简单的一句话总结,search是match的进化版,search比match方法好使。

匹配中文:

在某些情况下,我们想要匹配文本中的汉字,有一点需要注意的是,中文unicode编码范围主要在[u4e00-u9fa5]+,这样说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的。假设现在想把现在想把字符串title=’你好hello,世界’中的中文提取出来,可以这么做:

import re
title = '你好,hello,世界'
pattern = re.compile('[\u4e00-\u9fa5]+')
result = pattern.findall(title)
print(result) #['你好', '世界']

注意贪婪模式与非贪婪模式

1、贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配():
2、非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配(?):
当该字符紧跟在任何一个其他限制符 (
, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。
3、python里数量词默认是贪婪的。

(1)、使用贪婪的数量词

示例一:源字符串:abbbcc
(1)、使用贪婪的数量词ab*,匹配结果abbb


* 决定了尽可能多匹配 b,所以a后面所有的 b 都出现了

(2)、使用非贪婪的数量词

(2)、使用非贪婪的数量词的正则表达式ab*?,匹配结果: a。
即使前面有 *,但是 ? 决定了尽可能少匹配 b,所以没有 b。

示例二:源字符串:aa<div>test1</div>bb<div>test2cc
(1)、使用贪婪的数量词的正则表达式:<div>.*</div>

import re
s = 'aa<div>test1</div>bb<div>test2</div>cc'pattern1 = re.compile('<div>.*</div>')
result1 = pattern1.findall(s)
print(result1)
#['<div>test1</div>bb<div>test2</div>']

(2)、使用非贪婪模式的数量词的正则表达式:<div>.*?</div>

# 使用非贪婪模式的数量词的正则表达式:<div>.*?</div>
pattern2 = re.compile('<div>.*?</div>')
result2 = pattern2.findall(s)
# 匹配结果
print(result2) #['<div>test1</div>', '<div>test2</div>']

到这里就结束喽!听说,可以看到这里的人都很厉害的!

这篇python正则表达式颠覆你的人生观,详细到让你怀疑人生!相关推荐

  1. 网络爬虫学习软件篇-Python(一)下载安装(超详细教程,傻瓜式说明)

    很早就想学习一下网络爬虫了~苦于学艺不精并且过于懒惰以至于迟迟没有行动~最近因为项目做的也差不多了,就用空学习一下这门新的语言,了解一下新的技术.(PS:真的不会排版丑就丑点吧) 上面所说的傻瓜式说明 ...

  2. python 正则表达式 re.sub_Python 正则表达式 re.match/re.search/re.sub的使用解析

    From Python正则表达式 re.match(pattern, string, flags=0) 尝试从字符串起始位置匹配一个模式:如果不是起始位置匹配成功,则 re.match() 返回non ...

  3. python正则表达式入门_Python正则表达式教程之一:基础篇

    前言 之前有人提了一个需求,我一看此需求用正则表达式最合适不过.考虑到之前每次使用正则表达式,都是临时抱佛脚,于是这次我就一边完成任务一边系统的学习了一遍正则表达式.主要参考PyCon2016上的一个 ...

  4. Python 正则表达式入门(初级篇)

    唯心不易(转载) https://www.cnblogs.com/chuxiuhong/p/5885073.html Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门 ...

  5. Python正则表达式,看这一篇就够了

    作者 | 猪哥 来源 | 裸睡的猪(ID: IT--Pig) 大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中 ...

  6. 阅读后这篇文章后,python正则表达式完全弄懂了

    大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中关于 正则表达式的函数. re模块主要定义了9个常量.12个函 ...

  7. python 逆向生成正则表达式_一篇搞定Python正则表达式

    1. 正则表达式语法 1.1 字符与字符类 1 特殊字符:.^$?+*{}[]()| 以上特殊字符要想使用字面值,必须使用进行转义 2 字符类 1. 包含在[]中的一个或者多个字符被称为字符类,字符类 ...

  8. Python 正则表达式各种特殊符号 重点

    Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. r ...

  9. python正则表达式需要模块_使用Python正则表达式模块,让操作更加简单

    处理文本数据的一个主要任务就是创建许多以文本为基础的特性. 人们可能想要在文本中找出特定格式的内容,比如找出存在于文本中的电子邮件,或者大型文本中的电话号码. 虽然想要实现上述功能听起来很繁琐,但是如 ...

  10. Python正则表达式使用的四个基本步骤

    http://blog.itpub.net/31403259/viewspace-2157701/ Python正则表达式使用的四个基本步骤     1.用import re导入正则表达式模块     ...

最新文章

  1. $.ajax上传文件或者上传图片
  2. Neo4J简介(2)
  3. SQLite中SELECT基本形式
  4. EntityFramework Core是否可以映射私有属性呢?了解一下。
  5. VMware 全虚拟打开
  6. Android studio使用心得(二)— 打包签名apk发布
  7. eclipse 隐藏项目_前5个有用的隐藏Eclipse功能
  8. 新电脑到手要干的事情
  9. Bailian2767 简单密码(POJ NOI0107-10)【密码】
  10. 2014520420145212信息安全系统实验三报告
  11. 《信息管理学基础》——娄策群(第二版)第一章答案
  12. 带485接口伺服电机使用MODBUS协议控制
  13. 12个优秀的开源UML工具
  14. uniapp开发hbuilder连接安卓模拟器mumu
  15. 分享两个线+标注的SLD样式
  16. 供参考的一些APP推广渠道
  17. c语言个人所得税的打印思路,C语言编写一个计算个人所得税的程序,要求输入收入金额,能够输...
  18. Ubuntu 16.04 LTS 初体验 (转载)
  19. linux下的php编辑器
  20. java音视频开发技术_FFmpeg音视频核心技术精讲与实战

热门文章

  1. 邮件服务器公网IP被国外反垃圾联盟(PBL)列入黑名单移除操作方法
  2. NOI题解(1.1编程基础之输入输出)
  3. 用Photoshop抠图
  4. Linux查看CPU使用率的一些命令
  5. 嵌入式系统基础——Unbuntu的初步使用
  6. 如何选择企业邮箱?企业邮箱好处是什么?
  7. mac上的微信小助手WeChatPlugin
  8. 搜索神器Android,网盘搜索神器
  9. 论文阅读-A decade of social bot detection-Communications of the ACM, 2020(机器人检测的十年综述)
  10. 网站实现扫描二维码关注微信公众号,实现自动登陆