正则表达式

搭配[[Python]]

参考[[中谷教育-Python视频教程-26-正则表达式-初识]]

参考python官方re资料

参考正则表达式教程

参考Python正则表达式教程

工具正则测试网站

参考Python正则表达式,这一篇就够了! learning

参考[[字符编码]]



Python正则表达式,这一篇就够了!

graph LR 文章目录 文章目录---re模块简介 文章目录---re模块常量 文章目录---re模块函数 文章目录---re模块异常 文章目录---正则对象

re模块简介

re模块官方文档

re模块源码库

re模块主要定义了9个常量、12个函数、1个异常。

re模块常量

常量 语法 作用
IGNORECASE re.IGNORECASE 或简写为 re.I 进行忽略大小写匹配。
ASCII re.ASCII 或简写为 re.A 顾名思义,ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。
DOTALL re.DOTALL 或简写为 re.S DOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\n默认模式下.是不能匹配行符\n
MULTILINE re.MULTILINE 或简写为 re.M 多行模式,当某字符串中有换行符\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。
VERBOSE re.VERBOSE 或简写为 re.X re.VERBOSE 或简写为 re.X
LOCALE re.LOCALE 或简写为 re.L 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。
UNICODE re.UNICODE 或简写为 re.U 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python 3 默认字符串已经是Unicode,所以有点冗余。
DEBUG re.DEBUG 显示编译时的debug信息。
TEMPLATE re.TEMPLATE 或简写为 re.T 猪哥也没搞懂TEMPLATE的具体用处,源码注释中写着:disable backtracking(禁用回溯),有了解的同学可以留言告知!

常量总结

  1. 9个常量中,前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用处,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。
  2. 常量在re常用函数中都可以使用,查看源码可得知。
  3. 常量可叠加使用,因为常量值都是2的幂次方值,所以是可以叠加使用的,叠加时请使用 | 符号,请勿使用+ 符号!

re模块函数

re模块有12个函数,猪哥将以功能分类来讲解;这样更具有比较性,同时也方便记忆。

查找一个匹配项

查找并返回一个匹配项的函数有3个:search、match、fullmatch,他们的区别分别是:

  1. search: 查找任意位置的匹配项
  2. match: 必须从字符串开头匹配
  3. fullmatch: 整个字符串与正则完全匹配

案例1

import re

text = 'a猪哥大帅b,猪哥大帅b'
pattern = r'猪哥大帅b'

print('search:',re.search(pattern,text).group())
print('search:',re.search(pattern,text))
print('match:',re.match(pattern,text))
print('fullmatch',re.fullmatch(pattern,text))

输出

search: 猪哥大帅b
search: <re.Match object; span=(1, 6), match='猪哥大帅b'>
match: None
fullmatch None

案例2

text = '猪哥大帅b,猪哥大帅b'
pattern = r'猪哥大帅b'

print('search:',re.search(pattern,text).group())
print('search:',re.search(pattern,text))
print('match:',re.match(pattern,text).group())
print('match:',re.match(pattern,text))
print('fullmatch',re.fullmatch(pattern,text))

输出:

search: 猪哥大帅b
search: <re.Match object; span=(0, 5), match='猪哥大帅b'>
match: 猪哥大帅b
match: <re.Match object; span=(0, 5), match='猪哥大帅b'> fullmatch None

案例3

text = '猪哥大帅b'
pattern = r'猪哥大帅b'

print('search:',re.search(pattern,text).group())
print('search:',re.search(pattern,text))
print('match:',re.match(pattern,text).group())
print('match:',re.match(pattern,text))
print('fullmatch',re.fullmatch(pattern,text).group())
print('fullmatch',re.fullmatch(pattern,text))

输出:

search: 猪哥大帅b
search: <re.Match object; span=(0, 5), match='猪哥大帅b'>
match: 猪哥大帅b
match: <re.Match object; span=(0, 5), match='猪哥大帅b'>
fullmatch 猪哥大帅b
fullmatch <re.Match object; span=(0, 5), match='猪哥大帅b'>

查找多个匹配项

查找多项函数主要有:findall函数finditer函数

  1. findall: 从字符串任意位置查找,返回一个列表
  2. finditer:从字符串任意位置查找,返回一个迭代器

两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。

案例4

text = 'a猪哥大帅b,猪哥大帅b'
pattern = r'猪哥大帅b'

print('findall:',re.findall(pattern,text))
print('finditer:',list(re.finditer(pattern,text)))

输出:

findall: ['猪哥大帅b', '猪哥大帅b']
finditer: [<re.Match object; span=(1, 6), match='猪哥大帅b'>, <re.Match object; span=(7, 12), match='猪哥大帅b'>]

分割

re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数, flags表示模式,就是上面我们讲解的常量!

案例5

import re
text = 'a猪哥大帅b,b猪哥大帅b,c猪哥大帅b'
pattern = r','
print('split:',re.split(pattern,text,maxsplit=999,flags=re.IGNORECASE))

输出:

split: ['a猪哥大帅b', 'b猪哥大帅b', 'c猪哥大帅b']

注意:str模块也有一个 split函数 ,那这两个函数该怎么选呢?
str.split函数功能简单,不支持正则分割,而re.split支持正则。

1000次循环以内str.split函数更快,而循环次数1000次以上后re.split函数明显更快,而且次数越多差距越大!

所以结论是:在 不需要正则支持 且 数据量和数次不多 的情况下使用str.split函数更合适,反之则使用re.split函数。

替換

替换主要有sub函数subn函数,他们功能类似!

先来看看sub函数的用法:

re.sub(pattern, repl, string, count=0, flags=0) 函数参数讲解:repl替换掉string中被pattern匹配的字符, count表示最大替换次数,flags表示正则表达式的常量。

值得注意的是:sub函数中的入参:repl替换内容既可以是字符串,也可以是一个函数哦! 如果repl为函数时,只能有一个入参:Match匹配对象。

案例6

import re
text = '1猪哥大帅b,1猪哥大帅b,3猪哥大帅b'
pattern = r','
rep1 = '、'
print('sub-rep1为字符串:',re.sub(pattern,rep1,text,count=2,flags=re.IGNORECASE))

输出:

ub-rep1为字符串: 1猪哥大帅b、1猪哥大帅b、3猪哥大帅b

案例7

text = '1猪哥大帅b,2猪哥大帅b。3猪哥大帅b'
pattern = r',|。'

rep1 = lambda matchobj: ' ' if matchobj.group(0) != ',' else '、'

print('sub-rep1为函数:',re.sub(pattern,rep1,text,count=2,flags=re.IGNORECASE))

输出:

sub-rep1为函数: 1猪哥大帅b、2猪哥大帅b 3猪哥大帅b

定义

定义:正则表达式(regexp或者re)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过re模块实现。

概括

  • 正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行。

  • 正则表达式语言相对小型和受限(功能有限)

    • 并非所有字符串处理都可以用正则表达式完成。
  • 字符匹配

    • 普通字符
      • 大部分字母和字符一般都会和自身匹配
      • 如正则表达式test会和字符串"test"完全匹配
    • 元字符
      • . ^ $ * + ? {} [] \ | ()
  • []

    • 常用来制定一个字符集:[abc];[a-z]
    • 元字符在字符集中不起作用:[akm$]
    • 补集匹配不在区间范围内的字符:[^5]
  • ^

    • 匹配行首。除非设置MULTILINE标志,它只是匹配字符串的开始。在MULTILINE模式里,它可以直接匹配字符串中的每个换行。
  • $

    • 匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符后面的任何位置。

在python中使用正则表达式

需要导入re模块import re

定义正则表达式就是在定义一个字符串。

在python中使用[]

>>> import re
>>> s = r'abc'
>>> re.findall(s,"aaaaaaaaaaaaaaaaaaaaaaaaabcdef")
['abc']
>>> re.findall(s,"aaaaaaaabcdfaaaaaaaaaaaaaaaaabcdef")
['abc', 'abc']
>>> st = "top tip tqp twp tep"
>>> res = r"top"
>>> re.findall(res,st)
['top']
>>> 
>>> res = r"tip"
>>> re.findall(res,st)
['tip']
>>> 
>>> res = r"t[io]p"
>>> re.findall(res,st)
['top', 'tip']
>>> 
>>> res = r"t[^io]p"
>>> re.findall(res,st)
['tqp', 'twp', 'tep']

posted @ 2020-11-18 23:54  Dluff  阅读(249)  评论(0编辑  收藏  举报