什么是正则表达式

正则表达式就是用来匹配字符串的,给字符串定义一个规则,如果字符串符合规则,则为“匹配”,否则该字符串就是不合法

官方文档:https://docs.python.org/zh-cn/3/library/re.html

正表达式之字符组

在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示

正则表达式 说明
[0123456789] 匹配0到9之间的任意一个数字
[0-9] 匹配0到9之间的任意一个数字
[a-z] 匹配a到z之间的任意一个小写字母
[A-Z] 匹配A到Z之间的任意一个大写字母
[0-9a-zA-Z] 匹配任意一个数字或者大小写字母(没有顺序)

正则表达式之特殊符号

元字符 说明
. 匹配除换行符以外的任意字符
\\w 匹配数字、字母、下(划线后续筛选变量名可能用到)
\\d 匹配任意的数字
\\t 匹配一个制表符(tab键)
^ 匹配字符串的开始 eg:^9
(找9并且这个9必须在开头)
$ 匹配字符串的结尾 eg:$9
(找9并且这个9必须在末尾)
\\W 匹配非字母或数字或下划线
\\D 匹配非数字
a|b 匹配a或者b 管道符就是or(或)的意思
() 给正则表达式分组 不影响正则匹配
[] 字符组的概念(里面所有的数据都是或的关系)
[^] 上箭号出现在了中括号的里面意思是取反操作

正则表达式之量词

量词 说明
* 重复零次或者多次(默认就是多次:越多越好)
+ 重复一次或者多次(默认就是多次:越多越好)
? 重复零次或者一次(默认就是一次:越多越好)
{n} 重复n次
{n} 重复最少n次最多多次(越多越好)
{n,m} 重复n到m次(越多越好)

正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式,修饰符被指定为一个可选的标志。多个标志可以通过按位 |它们来指定

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

转义符\

在正则表达式中,有很多有特殊意义的是元字符,比如\n\s等,如果要在正则中匹配正常的”\n“而不是”换行符”就需要对”\“进行转义,变成”\\

正则 待匹配字符 匹配结果 说明
\\n \\n False 因为正则表达式中\\
有特殊意义,所以要匹配\\n
本身
\\n \\n True 转义\\
之后变成\\
,即可匹配
"\\\\\\\\n" "\\\\n" True 在python中,字符串中的\\
也需要转义,所以每一个字符串\\
又需要转义一次
r'\\n' r'\\n' True 在字符串之前加r
,让整个字符串不转义

补充:python中可以在字符串的前面加r取消转义,更加方便

贪婪匹配与非贪婪匹配

贪婪匹配

贪婪匹配在匹配字符串时总是尝试匹配尽可能多的字符

非贪婪匹配

与贪婪匹配相反,非贪婪匹配在匹配字符串时总是尝试匹配尽可能少的字符

量词默认都是贪婪匹配 如果想修改为非贪婪匹配 只需要在量词的后面加?即可

re模块

python中无法直接使用正则 需要借助于模块

re.findall方法

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表

语法

  1. re.findall(正则表达式,待匹配的文本,修饰符(可选))

使用

  1. import re
  2. res = re.findall('a', 'abababab')
  3. print(res) # 结果是所有符合条件的数据,并且组织成了列表
  4. # ['a', 'a', 'a', 'a']

group()

匹配对象函数来获取匹配表达式

匹配对象方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

re.search方法

扫描整个字符串并返回第一个成功的匹配,没有返回None

语法

  1. re.search(正则表达式,待匹配的文本,修饰符(可选))

使用

  1. res = re.search('a', 'abababab')
  2. print(res)
  3. # <_sre.SRE_Match object; span=(0, 1), match='a'>
  4. print(res.group())
  5. # a
  6. res = re.search('c', 'abababab')
  7. print(res)
  8. # None
  9. # print(res.group())
  10. # 报错

re.match方法

描整个字符串并返回第一个成功的匹配(re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None,而re.search匹配整个字符串,直到找到一个匹配)

语法

  1. re.match(正则表达式,待匹配的文本,修饰符(可选))

使用

  1. res = re.match('a', 'abababab')
  2. print(res)
  3. # <_sre.SRE_Match object; span=(0, 1), match='a'>
  4. res = re.match('a', 'bbababab')
  5. print(res)
  6. # None
  7. # print(res.group())
  8. # 报错

re.finditer方法

findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回

语法

  1. re.finditer(正则表达式,待匹配的文本,修饰符(可选))

使用

  1. res = re.finditer('a', 'abababab')
  2. print(res)
  3. # <callable_iterator object at 0x7fa10814f780>
  4. for i in res:
  5. print(i.group())
  6. # a
  7. # a
  8. # a
  9. # a

re.compile方法

针对多个地方需要用到相同的正则表达式,通过compile来将正则表达式进行“封装”,直接调用即可

语法

  1. re.compile(正则表达式,修饰符(可选))

使用

  1. import re

re.split方法

split方法按照能够匹配的子串将字符串分割后返回列表

语法

  1. re.split(正则表达式,待匹配的文本,分隔次数(默认是0所有),修饰符(可选))

使用

  1. import re
  2. res = re.split(r'\d+', 'a1b2a3b4a5b6a7b', )
  3. print(res)
  4. # ['a', 'b', 'a', 'b', 'a', 'b', 'a', 'b']
  5. res = re.split(r'\d+', 'a1b2a3b4a5b6a7b', 1)
  6. print(res)
  7. # ['a', 'b2a3b4a5b6a7b']

re模块补充

findall的优先级查询

  1. import re
  2. res = re.findall('a(b)c','abcabcabcabc')
  3. print(res) # 默认只展示括号内正则表达式匹配到的内容
  4. # ['b', 'b', 'b', 'b']
  5. res = re.findall('(a)(b)(c)','abcabcabcabc')
  6. print(res)
  7. # [('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c'), ('a', 'b', 'c')]
  8. res = re.findall('a(?:b)c','abcabcabcabc')
  9. print(res) # 也可以取消分组有限展示的机制,括号前面加 ?: (问号冒号)
  10. # ['abc', 'abc', 'abc', 'abc']

group详细使用

简单使用

  1. res = re.search('(a)(b)(c)', 'abcabcabcabc')
  2. print(res.group())
  3. # abc
  4. print(res.group(1)) # 通过索引的方式单独获取分组内匹配到的数据
  5. # a
  6. res = re.search('a(b)(c)', 'abcabcabcabc')
  7. print(res.group(1)) # 可以通过索引的方式单独获取分组内匹配到的数据
  8. # b

补充:针对searchmatch有几个分组group方法括号内最大就可以写几

给组起别名

  1. res = re.search('a(?P<word>b)(c)', 'abcabcabcabc') # 用法:(?P<名字>匹配规则)
  2. print(res.group('word')) # 通过“名字”匹配数据
  3. # b

split的优先级查询

  1. res = re.split(r'(\d+)', 'a1b2a3b4a5b6a7b') # 没有()不保留所匹配的项,但是有()却保留了匹配的项
  2. print(res)
  3. # ['a', '1', 'b', '2', 'a', '3', 'b', '4', 'a', '5', 'b', '6', 'a', '7', 'b']