【python】第一模块 步骤四 第一课、初始正则表达式

2023-03-14,,

一课、初始正则表达式

一、课程介绍

  1.1 课程概要

  步骤介绍

正则表达式入门及应用
正则的进阶
案例
综合项目实战

二、正则表达式的基本操作(多敲代码多做练习)

  2.1 什么是正则表达式

  什么是正则表达式

正则表达式(简称为regex)是一些有字符和特殊符号组成的字符串
能按照某种模式匹配一系列有相似特征的字符串          例如:[a-z]表示26个小写英文字母

  正则表达式中的符号

符号 描述 示例
literal 匹配文本字符串的字面值literal foo
re1|re2 匹配正则表达式re1或者re2 foo|bar
. 匹配任何字符(除了\n之外) b.b
^ 匹配字符串起始部分 ^Dear
$ 匹配字符串终止部分 /bin/*sh$
* 匹配0次或者多次前面出现的正则表达式 [A-Za-z0-9]*
+ 匹配1次或者多次前面出现的正则表达式 [a-z]+\.com
? 匹配0次或者1次前面出现的正则表达式 goo?
{N} 匹配N次前面出现的正则表达式 [0-9]{3}
{M,N} 匹配M~N次前面出现的正则表达式 [0-9]{5,9}
[...] 匹配来自字符集的任意单一字符 [aeiou]
[..x-y..] 匹配x~y范围中的任意单一字符 [0-9][A-Za-z]
[^...] 不匹配此字符集中出现的任何一个字符,包括某一范围的字符(如果在此字符集中出现) [^aeiou],[^A-Za-z0-9]
(*|+|?|{})? 用于匹配上面频繁出现/重复出现符号的非贪婪版本(*、+、?、{}) *?[a-z]
(...) 匹配封闭的正则表达式,然后另存为子组 ([0-9]{3})?,f(oo|u)bar

  正则表达式中的特殊字符

特殊字符 描述 示例
\d 匹配任何十进制数字,与[0-9]一致(\D与\d相反,不匹配任何非数值型的数字)  data\d+.txt
\w 匹配任何字母数字字符,与[A-Za-z0-9]相同(\W与之相反)  [A-Za-z_]\w+
\s 匹配任何空格字符,与[\n\t\r\v\f]相同(\S与之相反)  of\sthe
\b 匹配任何单词边界(\B与之相反)  \bThe\b
\N 匹配已保存的子组N(参见上面的(...))  price:\16
\c 逐字匹配任何特殊字符c(即,仅按照字面意义匹配,不匹配特殊含义)  \.,\\,\*
\A(\Z) 匹配字符串的起始(结束)(另见上面介绍的^和$) \ADear

  正则表达式中的扩展表示法

扩展表示法 描述 示例
(?iLmsux) 在正则表达式中嵌入一个或者多个特殊"标记"参数(或者通过函数/方法) (?x),(?im)
(?:…) 表示一个匹配不用保存的分组 (?:\w+\.)*
(?P<name>…) 像一个仅由name标识而不是数字ID标识的正则分组匹配 (?P<data>)
(?P=name) 在同一字符串中匹配由(?P<name)分组的之前文本 (?P=data)
(?#…) 表示注释,所有内容都被忽略 (?#comment)
(?=…) 匹配条件是如果…出现在之后的位置,而不使用输入字符串;称作正向前视断言 (?=.com)
(?!…) 匹配条件是如果…不出现在之后的位置,而不使用输入字符串;称作负向前视断言 (?!.net)
(?<=…) 匹配条件是如果…出现在之前的位置,而不使用输入字符串;称作正向后视断言 (?<=800-)
(?<!…) 匹配条件是如果…不出现在之前的位置,而不使用输入字符串;称作负向后视断言 (?<!192\.168\.)
(?(id/name)Y|N) 如果分组所提供的id或name(名称)存在,就返回正则表达式的条件匹配Y,如果不存在,就返回N;|N是可选项 (?(1)y|x)

  使用正则表达式

简单匹配:例如:abc=>abc
多个匹配模式:例如:abc|12c=>abc,12c
匹配任意字符(.),除\n之外:例如:.=>abc.12c

  2.2 正则表达式的使用

  使用正则表达式

*匹配0次或者多次
+匹配一次或者多次
?匹配0次或者一次
{N}匹配指定的N次
{M,N}匹配M-N次,最大化优先

  2.3 正则表达式匹配同类型及边界匹配

  匹配同类型

\d匹配数字
\w匹配数字和字母
\s匹配任何空格字符

  边界匹配

用^匹配以**开头
用$匹配以**结尾

  2.4 正则表达式匹配选项

  匹配特殊字符

需要用“\”进行转义
使用[]指定要匹配的集合
使用[^]指定不要匹配的内容

  2.5 正则表达式分组

  正则表达式分组

重复一个字符串时
使用()进行分组,使用(?<word>\w+)指定组名
从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推
使用()对匹配的内容分组
使用\1、\2反向引用

  2.6 贪婪模式vs非贪婪模式

  贪婪模式vs非贪婪模式

贪婪匹配

在整个表达式匹配成功的前提下,尽可能多的匹配
非贪婪匹配
在整个表达式匹配成功的前提下,以最少的匹配字符
默认是贪婪模式

  

贪婪模式举例

表达式ab.+c

      测试数据:abacaxcd

      匹配结果:abacaxc

非贪婪模式

只需要在匹配pattern中加上“?”
表达式ab.*?c

      测试数据:abacaxcd

      匹配结果:abac

三、 实战:正则表达式的应用

  实战:身份证号码的正则匹配

  正则表达式联系

身份证号码匹配正则表达式编写
电子邮箱正则表达式

四、 正则表达式进阶

  4.1 正则的进阶介绍

  课程概要

re模块
findall()的使用
search()的使用
group()与groups()的使用
split()正则分割
Sub()正则替换

  课程目标

掌握compile()和match()函数的使用
掌握findall()和search()函数的使用
math()和search()的区别
掌握group()、groups()、groupdict()的基本使用
掌握split()、sub()的基本使用

  教学思路

先理论
后代码实战
跟着来

  4.2 re模块介绍

  re模块

属性 描述
re.I、re.IGNORECASE 不区分大小写的匹配
re.L、re.LOCALE 根据所使用的本地语言环境通过\w、\W、\b、\B、\s、\S实现匹配
re.M、re.MULTILINE ^和$分别匹配目标字符串中行的起始和结尾,而不是严格匹配整个字符串本身的起始和结尾
re.S、re.DOTALL “.”(点号)通常匹配除了\n(换行符)之外的所有单个字符;该标记表示“.”(点号)能够匹配全部字符
re.X、re.VERBOSE 通过反斜杠转义,否则所有空格加上#(以及在该行中所有后续文字)都被忽略,除非在一个字符类中或者允许注释并且提高可读性

  re模块-compile

compile(pattern,flag = 0)
使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象
推荐编译,但它不是必须的

  re模块-match

match(pattern,string,flag = 0)
尝试使用带有可选的标记的正则表达式的模式来匹配字符串。如果匹配成功,就返回匹配对象;如果失败,就返回None

 1 import re
2
3 # 将正则表达式编译
4 pattern = re.compile(r'hello', re.I)
5 print(dir(pattern))
6
7 # 通过match进行匹配
8 rest = pattern.match('Hello,world')
9 print(rest)
10 print(dir(rest))
11 print('string', rest.string)
12 print('re:', rest.re)
13 print(rest.groups())

  4.3 findall和search

  findall()的使用

findall(pattern,string[,flags])
查找字符串中所有(非重复)出现的正则表达式模式,并返回一个匹配列表

 1 import re
2
3 # 找出一下字符串中的数字
4
5 content = 'One1Two22three333four4444five55555six666666'
6
7 # 使用编译的对象
8 p = re.compile(r'[a-z]+', re.I)
9 rest = p.findall(content)
10 print(rest)
11
12 # 不编译
13 all_rest = re.findall(r'[a-z]+', content, re.I)
14 print(all_rest)

  search()的使用

search(pattern,string, flags = 0)
使用可选标记搜索字符串中第一次出现的正则表达式模式。如果匹配成功,则返回匹配对象;如果失败,则返回None

 1 import re
2
3 # 找出一下字符串中的数字
4
5 content = 'hello, world'
6
7 # 使用编译的对象
8 p = re.compile(r'world')
9 # 使用search
10 rest = p.search(content)
11 print(rest)
12
13 # 使用match
14 rest_match = p.match(content)
15 print(rest_match)
16
17 # 使用函数进行调研
18 rest_func = re.search(r'world', content)
19 print(rest_func)

  4.4 正则表达式的分组(group()与groups())

  group()与groups()的使用

group(num)返回整个匹配对象或编号为num的特定子组
groups():返回一个包含所有匹配子组的元组(如果没有成功匹配,则返回一个空组)

 1 import re
2
3 def test_group():
4 content = 'hello, world'
5 p=re.compile(r'world')
6 rest = p.search(content)
7 print(rest)
8 if rest:
9 # group的使用
10 print(rest.group())
11 # groups的使用
12 print(rest.groups())
13
14
15
16 def test_id_card():
17 """身份证号码正则匹配"""
18 # p = re.compile(r'(\d{6})(\d{4})((\d{2})(\d{2}))(\d{2}\d{1})([0-9]|X)')
19 p = re.compile(r'(\d{6})(?P<year>\d{4})((?P<mouth>\d{2})(?P<day>\d{2}))(\d{2}\d{1})([0-9]|X)')
20 # 准备两个身份证号
21 id ='230381199310070329'
22 rest1 = p.search(id)
23 print(rest1.group(2))
24 print(rest1.groups())
25 print(rest1.groupdict())
26
27 if __name__ == '__main__':
28 #test_group()
29 test_id_card()

  4.5 正则表达式的分割和替换

  split()正则分割

split(pattern, string, max=0)
根据正则表达式的模式分隔符,split函数将字符串分割为列表,然后返回成功匹配的列表,分割最多操作max次(默认分割所有匹配成功的位置)

 1 import re
2
3 """
4 使用split正则分割字符串
5 """
6
7 s = 'one1two2three3four4five5six6'
8 p = re.compile(r'\d+')
9 rest = p.split(s, 2)
10 print(rest)

  sub()正则替换

sub(pattern,repl,string,max=0)
使用repl替换string中每一个匹配的子串后返回替换后的字符串,最多操作max次(默认替换所有)

 1 import re
2
3 """
4 使用正则表达式进行替换
5 """
6 s = 'one1two2three3four4five5six6'
7 # one@two@three@four@five@six@
8
9 #使用正则替换
10 p = re.compile(r'\d+')
11 rest = p.sub('@', s)
12 print(rest)
13
14 # 使用字符串原始替换方式
15 rest_origin = s.replace('1', '@').replace('2', '@').replace('3', '@').replace('4', '@').replace('5', '@').replace('6', '@')
16 print(rest_origin)
17
18 s2 = 'hello world'
19 # 使用正则表达式
20 p2 = re.compile(r'(\w+) (\w+)')
21 rest_pos = p2.sub(r'\2 \1', s2)
22 print(rest_pos)
23
24
25 # 在原有的内容基础上,替换并改变内容
26 def f(m):
27 """使用函数进行替换规则改变"""
28 return m.group(2).upper() + ' ' + m.group(1)
29
30
31 rest_change = p2.sub(f, s2)
32 print(rest_change)
33
34
35 # 使用匿名函数进行替换 lambda
36 rest_lamb = p2.sub(lambda m: m.group(2).upper() + ' ' + m.group(1), s2)
37 print('--------')
38 print(rest_lamb)

五、 正则综合实战(多练多看)

  5.1 实战:正则匹配图片地址的需求分析

# 1. 下载html
# 2. 写正则的规则
# 要找到img标签
# 找到src属性
# <img class="" style="" src="xxx" xx="">
# <img.+src=\".+\".+>

  5.2 实战:代码实现正则匹配图片地址

 1 import re
2
3 def test_re_img():
4 """ 使用正则表达式找到图片的地址 """
5 # 1.读取html
6 with open('img.html', encoding='utf-8') as f:
7 html = f.read()
8 # print(html)
9 # 2. 准备正则
10 p = re.compile(r'<img.+?src=\"(?P<src>.+?)\".+?>', re.I)
11 # 使用findall找到图片的列表
12 list_img = p.findall(html)
13 print(len(list_img))
14 for ls in list_img:
15 print(ls.replace('&amp;', '&'))
16 #TODO 使用urllib,requests将图片保存
17
18
19
20 if __name__ == '__main__':
21 test_re_img()

六、 课程总结

  课程总结

什么是正则表达式
正则表达式匹配N次
匹配同类型及边界匹配
正则表达式匹配选项
正则表达式分组
贪婪模式VS非贪婪模式
正则表达式分析练习

  知识点回顾

什么是正则表达式

正则表达式(简称为regex)是一些由字符和特殊符号组成的字符串
能按照某种模式匹配一系列有相似特征的字符串
例如:[a-z]表示26个小写字母
使用正则表达式
简单匹配:例如:abc => abc
多个匹配模式:例如:abc|12c =>abc,12c
匹配任意字符(.),除\n之外:例如:. => abc, 12c
*匹配0次或者多次
+匹配一次或者多次
?匹配0次或者1次
{N}匹配指定的N次
{M-N}匹配M-N次,最大化优先
匹配同类型
\d匹配数字
\w匹配数字和字母
\s匹配任何空格字符
边界匹配
用^匹配以**开头
用$匹配以**结尾
匹配特殊字符
需要用“\”进行转义
指定匹配选项
使用[]指定要匹配的集合
使用[^]指定不要匹配的内容
正则表达式分组
重复一个字符串时
使用()进行分组,使用(?<word>\w+)指定组名
从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推
使用()对匹配的内容分组
使用\1、\2反向引用
贪婪模式VS非贪婪模式
贪婪模式

在整个表达式匹配成功的前提下,尽可能多的匹配
非贪婪模式
在整个表达式匹配成功的前提下,以最少的匹配字符
只需在匹配pattern中加上“?”
表达式ab.*?c
测试数据:abacaxcd
匹配数据:abac
默认是贪婪模式
正则表达式练习
身份证号码匹配正则表达式编写
电子邮箱正则表达式编写
手机号码正则表达式编写

  重点知识

理解什么是正则表达式以及它的用途
正则表达式的基本语法
正则表达式的编写和验证
正则表达式的分组及反向引用

  难点知识

正则表达式的贪婪与非贪婪模式
正则表达式的分析方法

【python】第一模块 步骤四 第一课、初始正则表达式的相关教程结束。

《【python】第一模块 步骤四 第一课、初始正则表达式.doc》

下载本文的Word格式文档,以方便收藏与打印。