别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

    • 基础篇

    • 进阶篇

      • Python 全栈之路系列之迭代器与生成器
      • Python 全栈之路系列之装饰器
      • Python 标准库系列之模块默认全局变量
      • Python 全栈之路系列之异常处理
      • Python 全栈之路系列之文件操作
      • Python 全栈之路系列之递归
      • Python 全栈之路系列之反射
      • Python 全栈之路系列之正则表达式 re 模块
        • 正则表达式概念
        • 字符匹配
        • 次数匹配
        • 边界匹配
        • 正则表达式分组匹配
        • re 模块常用的方法
        • 实例
      • Python 全栈之路系列之字符串格式化
    • 面向对象

    • 网络编程

    • 操作系统

    • 标准库

    • 第三方库

    • Python 全栈之路
  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 全栈之路
  • 进阶篇
佚名
2020-05-23
目录

Python 全栈之路系列之正则表达式 re 模块

正则表达式并不是 Python 的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如 str 自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。

# 正则表达式概念

  1. 使用单个字符串来描述匹配一系列符合某个句法规则的字符串
  2. 是对字符串操作的一种逻辑公式
  3. 应用场景:处理文本和数据
  4. 正则表示是过程:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;否则匹配失败

# 字符匹配

字符 描述
. 匹配任意一个字符(除了\n)
\d \D 数字/非数字
\s \S 空白/非空白字符
\w \W 单词字符[a-zA-Z0-9]/非单词字符
\b \B 单词边界,一个\w 与\W 之间的范围,顺序可逆/非单词边界
  • 匹配任意一个字符
 # 匹配字符串abc,.代表b
 >>> re.match('a.c','abc').group()
'abc'
1
2
3
  • 数字与非数字
 # 匹配任意一数字
 >>> re.match('\d','1').group()
'1'
 # 匹配任意一个非数字
 >>> re.match('\D','a').group()
'a'
1
2
3
4
5
6
  • 空白与非空白字符
 # 匹配任意一个空白字符
 >>> re.match("\s"," ").group()
' '
 # 匹配任意一个非空白字符
 >>> re.match("\S","1").group()
'1'
 >>> re.match("\S","a").group()
'a'
1
2
3
4
5
6
7
8
  • 单词字符与非单词字符

单词字符即代表[a-zA-Z0-9]

 # 匹配任意一个单词字符
 >>> re.match("\w","a").group()
'a'
 >>> re.match("\w","1").group()
'1'
 # 匹配任意一个非单词字符
 >>> re.match("\W"," ").group()
' '
1
2
3
4
5
6
7
8

# 次数匹配

字符 匹配
* 匹配前一个字符 0 次或者无限次
+ 匹配前一个字符 1 次或者无限次
? 匹配前一个字符 0 次或者 1 次
{m}/{m,n} 匹配前一个字符 m 次或者 N 次
*?/+?/?? 匹配模式变为贪婪模式(尽可能少匹配字符)
  • 介绍
字符 匹配
prev? 0 个或 1 个 prev
prev* 0 个或多个 prev,尽可能多地匹配
prev*? 0 个或多个 prev,尽可能少地匹配
prev+ 1 个或多个 prev,尽可能多地匹配
prev+? 1 个或多个 prev,尽可能少地匹配
prev{m} m 个连续的 prev
prev{m,n} m 到 n 个连续的 prev,尽可能多地匹配
prev{m,n}? m 到 n 个连续的 prev,尽可能少地匹配
[abc] a 或 b 或 c
[^abc] 非(a 或 b 或 c)
  • 匹配前一个字符 0 次或者无限次
 >>> re.match('[A-Z][a-z]*','Aaa').group()
'Aaa'
 >>> re.match('[A-Z][a-z]*','Aa').group()
'Aa'
 >>> re.match('[A-Z][a-z]*','A').group()
'A'
1
2
3
4
5
6
  • 匹配前一个字符 1 次或者无限次
 # 匹配前一个字符至少一次,如果一次都没有就会报错
 >>> re.match('[A-Z][a-z]+','A').group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
1
2
3
4
5
 >>> re.match('[A-Z][a-z]+','Aa').group()
'Aa'
 >>> re.match('[A-Z][a-z]+','Aaaaaaa').group()
'Aaaaaaa'
1
2
3
4
  • 匹配前一个字符 0 次或者 1 次
 >>> re.match('[A-Z][a-z]?','A').group()
'A'
 # 只匹配出一个a
 >>> re.match('[A-Z][a-z]?','Aaaa').group()
'Aa'
1
2
3
4
5
  • 匹配前一个字符 m 次或者 N 次
 #匹配前一个字符至少5次
 >>> re.match('\w{5}','asd234').group()
'asd23'
 # 匹配前面的字符6-10次
 >>> re.match('\w{6,10}','asd234').group()
'asd234'
 # 超过的字符就匹配不出来
 >>> re.match('\w{6,10}','asd2313qeadsd4').group()
'asd2313qea'

1
2
3
4
5
6
7
8
9
10
  • 匹配模式变为贪婪模式
 >>> re.match(r'[0-9][a-z]*','1bc').group()
'1bc'
 # *?匹配0次或者多次
 >>> re.match(r'[0-9][a-z]*?','1bc').group()
'1'
 # +?匹配一次或者多次,但是只匹配了一次
 >>> re.match(r'[0-9][a-z]+?','1bc').group()
'1b'
 # ??匹配0次或者一次
 >>> re.match(r'[0-9][a-z]??','1bc').group()
'1'
1
2
3
4
5
6
7
8
9
10
11

贪婪匹配和非贪婪匹配

# 边界匹配

字符 匹配
^ 匹配字符串开头
$ 匹配字符串结尾
\A \Z 指定的字符串必须出现在开头/结尾
  • 匹配字符串开头
 # 必须以指定的字符串开头,结尾必须是@163.com
 >>> re.match('^[\w]{4,6}@163.com$','asdasd@163.com').group()
'asdasd@163.com'
1
2
3
  • 匹配字符串结尾
 # 必须以.me结尾
 >>> re.match('[\w]{1,20}.me$','ansheng.me').group()
'ansheng.me'
1
2
3
  • 指定的字符串必须出现在开头/结尾
 >>> re.match(r'\Awww[\w]*\me','wwwanshengme').group()
'wwwanshengme'
1
2

# 正则表达式分组匹配

  • | 匹配左右任意一个表达式
 >>> re.match("www|me","www").group()
'www'
 >>> re.match("www|me","me").group()
'me'
1
2
3
4
  • (ab) 括号中表达式作为一个分组
# 匹配163或者126的邮箱
 >>> re.match(r'[\w]{4,6}@(163|126).com','asdasd@163.com').group()
'asdasd@163.com'
 >>> re.match(r'[\w]{4,6}@(163|126).com','asdasd@126.com').group()
'asdasd@126.com'
1
2
3
4
5
  • (?P) 分组起一个别名
 >>> re.search("(?P<zimu>abc)(?P<shuzi>123)","abc123").groups()
('abc', '123')
1
2
  • 引用别名为 name 的分组匹配字符串
 >>> res.group("shuzi")
'123'
 >>> res.group("zimu")
'abc'
1
2
3
4

# re 模块常用的方法

  • re.match()

语法格式:

match(pattern, string, flags=0)
1

释意:

Try to apply the pattern at the start of the string, returning a match object, or None if no match was found.

实例:

 # 从头开始匹配,匹配成功则返回匹配的对象
 >>> re.match("abc","abc123def").group()
'abc'
 # 从头开始匹配,如果没有匹配到对应的字符串就报错
 >>> re.match("\d","abc123def").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
1
2
3
4
5
6
7
8
  • re.search()

语法格式:

search(pattern, string, flags=0)
1

释意:

Scan through string looking for a match to the pattern, returning a match object, or None if no match was found.

实例:

 # 匹配整个字符串,匹配到第一个的时候就返回匹配到的对象
 >>> re.search("\d","abc1123def").group()
'1'
1
2
3
  • re.findall()

语法格式:

findall(pattern, string, flags=0)
1

释意:

Return a list of all non-overlapping matches in the string.

实例:

 # 匹配字符串所有的内容,把匹配到的字符串以列表的形式返回
 >>> re.findall("\d","abc123def456")
['1', '2', '3', '4', '5', '6']
1
2
3
  • re.split

语法格式:

split(pattern, string, maxsplit=0)
1

释意:

Split the source string by the occurrences of the pattern, returning a list containing the resulting substrings.

实例:

 # 指定以数字进行分割,返回的是一个列表对象
 >>> re.split("\d+","abc123def4+-*/56")
['abc', 'def', '+-*/', '']
 # 以多个字符进行分割
 >>> re.split("[\d,]","a,b1c")
['a', 'b', 'c']
1
2
3
4
5
6
  • re.sub()

语法格式:

sub(pattern, repl, string, count=0)
1

释意:

Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used.

实例:

 # 把abc替换成def
 >>> re.sub("abc","def","abc123abc")
'def123def'
 # 只替换查找到的第一个字符串
 >>> re.sub("abc","def","abc123abc",count=1)
'def123abc'
1
2
3
4
5
6

# 实例

string 方法包含了一百个可打印的 ASCII 字符,大小写字母、数字、空格以及标点符号

 >>> import string
 >>> printable = string.printable
 >>> printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
1
2
3
4
 >>> import re
 # 定义的字符串
 >>> source = '''I wish I may, I wish I migth
... Hava a dish of fish tonight.'''
 # 在字符串中检索wish
 >>> re.findall('wish',source)
['wish', 'wish']
 # 对源字符串任意位置查询wish或者fish
 >>> re.findall('wish|fish',source)
['wish', 'wish', 'fish']
 # 从字符串开头开始匹配wish
 >>> re.findall('^wish',source)
[]
 # 从字符串开头匹配I wish
 >>> re.findall('^I wish',source)
['I wish']
 # 从字符串结尾匹配fish
 >>> re.findall('fish$',source)
[]
 # 从字符串结尾匹配fish tonight.
 >>> re.findall('fish tonight.$',source)
['fish tonight.']
 # 查询以w或f开头,后面紧跟着ish的匹配
 >>> re.findall('[wf]ish',source)
['wish', 'wish', 'fish']
 # 查询以若干个w\s\h组合的匹配
 >>> re.findall('[wsh]+',source)
['w', 'sh', 'w', 'sh', 'h', 'sh', 'sh', 'h']
 # 查询以ght开头,后面紧跟着一个非数字和字母的匹配
 >>> re.findall('ght\W',source)
['ght.']
 # 查询已以I开头,后面紧跟着wish的匹配
 >>> re.findall('I (?=wish)',source)
['I ', 'I ']
 # 最后查询以wish结尾,前面为I的匹配(I出现次数尽量少)
 >>> re.findall('(?<=I) wish',source)
[' wish', ' wish']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
  • 匹配时不区分大小写
 >>> re.match('a','Abc',re.I).group()
'A'
1
2
  • r 源字符串,转义,如果要转义要加两个\n
 >>> import re
 >>> pa = re.compile(r'ansheng')
 >>> pa.match("ansheng.me")
<_sre.SRE_Match object; span=(0, 7), match='ansheng'>
 >>> ma = pa.match("ansheng.me")
 >>> ma
<_sre.SRE_Match object; span=(0, 7), match='ansheng'>
 # 匹配到的值存到group内
 >>> ma.group()
'ansheng'
 # 返回字符串的所有位置
 >>> ma.span()
(0, 7)
 # 匹配的字符串会被放到string中
 >>> ma.string
'ansheng.me'
 # 实例放在re中
 >>> ma.re
re.compile('ansheng')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
编辑 (opens new window)
#编码#正则表达式
上次更新: 2024-07-23, 01:00:43
Python 全栈之路系列之反射
Python 全栈之路系列之字符串格式化

← Python 全栈之路系列之反射 Python 全栈之路系列之字符串格式化→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式