re简介
正则表达式其本身就是一种小型的,高度专业化的编程语言。
在Python中,它被内嵌在了re模块里面,正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。
本文仅针对可能用到的方法进行描述,对不常用的方法等进行了筛选。
方法一览
符号大全
以下是正则表达式的符号大全:
符号 | 中文名称 | 释义 |
---|---|---|
. | 通配符 | 匹配除\n之外的任意字符,如果想匹配\n可更换匹配模式为re.S或re.DOTALL |
^ | 开始符 | 匹配以特定字符开始的字符串,在检测时只会检测开头第一个字符并立即返回结果 |
$ | 结束符 | 匹配以特定字符结尾的字符串,在检测时只会检测结尾最后一个字符并立即返回结果 |
* | 可有重复符 | 代表可以取0-∞位*号前面的字符(默认贪婪取值,可通过?取消贪婪模式) |
+ | 必有重复符 | 代表可以取1-∞位+号前面的字符(默认贪婪取值,可通过?取消贪婪模式) |
? | 单一重复符 | 代表可以取1-∞位?号前面的字符(默认贪婪取值,可通过?取消贪婪模式) |
{n,m} | 范围重复符 | 代表可以取到n-m位{n,m}前面的字符(默认贪婪取值,可通过?取消贪婪模式) |
{n} | 精确重复符 | 代表可以精确取到n位{n}前面的字符 |
[] | 字符集 | 在[]中多个字符仅能匹配到1个,并且字符集中所有符号失去特殊意义,仅有- ^ \ 这3个符号在字符集中具有特殊意义 |
[-] | 区间符 | 字符集中的-号代表可以取从多少到多少区间的值,按照ASCII码排序,比如[a-z0-9A-Z]代表这1位取全部的英文字母和数字 |
[^] | 排除符 | 字符集中的号代表非的作用,比如[0-9]代表这1位并非是数字 |
[\] | 转义符 | 转义符如果在字符集中使用,可以为特定的字符赋予特殊的意义 |
\ | 转义符 | 转义符如果在字符集外使用,可以为特定的字符赋予特殊的意义,并且还可以让特定的字符失去特殊的意义,但是如果未用r原始字符串进行正则匹配,则可能会导致令人意外的情况发生 |
\d | … | 匹配任何十进制数,它相当于在字符集中使用[0-9] |
\D | … | 匹配任何非十进制数,它相当于在字符集中使用[^0-9] |
\s | … | 匹配任何空白字符,它相当于在字符集中使用[\t\n\r\f\v] |
\S | … | 匹配任何非空白字符,它相当于在字符集中使用[^\t\n\r\f\v] |
\w | … | 匹配任何字母数字下划线字符,它相当于在字符集中使用[a-z A-Z 0-9] |
\W | … | 匹配任何非字母数字下划线字符,它相当于在字符集中使用[a-z A-Z 0-9] |
\b | … | 匹配一个特殊字符边界,比如空格,&.#等(不常用) |
| | 管道符 | 相当于或,注意与字符集里的区别,管道符将前后分为2段,左右看做1个整体,而字符集中的或仅仅代表从众多选项中拿出1个 |
() | 分组符 | 将多个元素字符看做一个整体,也就是将它们当做一个元素字符进行匹配,若整个匹配规则中无子分组,则默认的匹配结果为一组 |
(?=exp) | 零宽先行断言 | 匹配后面为exp的内容 |
(?<=exp) | 零宽后行断言 | 匹配前面为exp的内容 |
(?!exp) | 零宽负向先行断言 | 匹配后面不能是exp的内容 |
(?<!exp) | 零宽负向后行断言 | 匹配前面不能是exp的内容 |
匹配方法
以下是re模块提供的正则匹配方法:
方法 | 描述 |
---|---|
findall() | 将所有的匹配结果返回至1个列表中 |
finditer() | 将所有的匹配结果返回至1个迭代器中 |
search() | 将首次匹配的结果返回至search对象中,可通过group()进行取值 |
match() | 在search()基础上添加了^,使之只能在开头匹配 |
group() | 通过该方法对search对象进行取值操作,返回一个或者多个匹配的子组 |
groups() | 通过该方法对search对象进行取值操作,返回一个元组,包含所有匹配的子组 |
groupdict() | 通过该方法对search对象进行取值操作,返回一个字典,包含了所有的具名子组 |
split() | 对字符串进行分割,其算法可能导致令人意外的情况发生 |
sub() | 对字符串进行替换,最少需要3个参数,返回一个新的字符串 |
subn() | 对字符串进行替换,最少需要3个参数,返回一个元祖,其中包含了替换成功了几次 |
complie() | 可以将一个标示符赋予指定的规则,达到简化重复操作的目的 |
匹配模式
以下是re模块提供的正则匹配模式:
模式简写 | 模式全写 | 描述 |
---|---|---|
re.I | re.IGNORECASE | 不分大小写字母的匹配模式 |
re.M | re.MULTILINE | 视为多行的匹配模式,以\n作为行分割符 |
re.S | re.DOTALL | 视为单行的匹配模式,即通配符可以匹配\n |
re.U | re.UNICODE | 宽字符匹配模式,即支持匹配占4个字符的UTF-16匹配模式 |
创建正则
re.findall()
在测试阶段,我们大部分示例都会使用re.findall()方法进行测试。
它的函数签名如下:
def findall(pattern, string, flags=0):
参数释义:
- pattern:匹配规则
- string:被匹配字符串
- flags:匹配模式
一次简单的使用,匹配以hello开头且以exp结尾的子串,采用多行匹配模式:
import re
string = "hello world\nhello regexp\nhello python\n"
resultList = re.findall(
pattern=r"^hello.*exp$",
string=string,
flags=re.M
)
print(resultList)
# ['hello regexp']
基础符号
. 通配符
.通配符会匹配除\n之外的任意字符,如果想匹配\n可更换匹配模式为re.S或re.DOTALL。
如下示例,匹配11个除开\n之外的任意字符组成的子串:
import re
rule = "." * 11
string = "hello world\n123456abcdeABCDE"
resultList = re.findall(pattern=rule, string=string)
print(resultList)
# ['hello world', '123456abcde']
^ 开始符
^开始符会匹配以特定字符开始的字符串,在检测时只会检测开头第一个字符并立即返回结果。
如下示例,匹配以P开头且后面必须是ython加上7个除开\n的任意字符的子串:
import re
rule = "^Python......."
string = "Python regexp module"
resultList = re.findall(pattern=rule, string=string)
print(resultList)
# ['Python regexp']
$ 结束符
$结束符会匹配以特定字符结尾的字符串,在检测时只会检测结尾最后一个字符并立即返回结果。
如下所示,匹配以p结束,且前面2个字符必须是E与x的子串,区分大小写:
import re
rule = "Exp$"
string = "Python regexp regExp RegExp"
resultList = re.findall(pattern=rule, string=string)
print(resultList)
# ['Exp']
重复符
* 可有重复
*代表可以取0-∞位*号前面的字符(默认贪婪取值,可通过?取消贪婪模式)
如下示例,匹配必须是以h开头,后面可以有0个也可以有多个除了\n外的任意字符,紧接着\n后继续匹配0个或者n个除了\n外的任意字符,最后必须以p进行结尾的子串:
import re
rule = "^h.*\n.*p$"
string = "hello Python\nregexp"
resultList = re.findall(pattern=rule, string=string)
print(resultList)
# ['hello Python\nregexp']
上面这个示例,有3个条件是必须的。
- h开头
- 中间必须有\n
- p结束
所以下面这个字符串也会被匹配到:
string = "h\np"
+ 必有重复
+代表可以取1-∞位+号前面的字符(默认贪婪取值,可通过?取消贪婪模式)
如下示例,匹配必须是以h开头,后面可以有1个也可以有多个除了\n外的任意字符,紧接着\n后继续匹配1个或者n个除了\n外的任意字符,最后必须以p进行结尾的子串:
import re
rule = "^h.+\n.+p$"
string = "hello Python\nregexp"
resultList = re.findall(pattern=rule, string=string)
print(resultList)
# ['hello Python\nregexp']
上面这个示例,有5个条件是必须的:
- h开头
- h后面必须至少有1个任意字符
- 中间必须有\n
- \n后面必须至少有1个任意字符
- p结束
所以下面这个字符串不会被匹配到:
string = "h\np"
? 单一重复
?代表可以取1-∞位?号前面的字符(默认贪婪取值,可通过?取消贪婪模式)
如下示例,匹配可以是1开头,也可以不是1开头且后面是2345678且以9结尾的字符串:
import re
rule = "^1?23456789$"
string = "123456789"
resultList = re.findall(pattern=rule, string=s