• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
喵了个喵0507
博客园             管理     
【python】第一模块 步骤四 第一课、初始正则表达式

第一课、初始正则表达式

一、课程介绍

  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
    • 默认是贪婪模式
  • 正则表达式练习
    • 身份证号码匹配正则表达式编写
    • 电子邮箱正则表达式编写
    • 手机号码正则表达式编写

  重点知识

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

  难点知识

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

 

posted on 2020-01-08 13:58  喵了个喵0507  阅读(308)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3