常用表达式

字符

描述

\d

代表任意数字,就是阿拉伯数字 0-9 这些玩意。

​\D​

大写的就是和小写的唱反调,\d 你代表的是任意数字是吧?那么我 \D 就代表不是数字的。

​\w​

代表字母,数字,下划线。也就是 a-z、A-Z、0-9、_。

​\W​

跟 \w 唱反调,代表不是字母,不是数字,不是下划线的。

​\n​

代表一个换行。

​\r​

代表一个回车。

​\f​

代表换页。

​\t​

代表一个 Tab 。

​\s​

代表所有的空白字符,也就是上面这个:\n、\r、\t、\f。

​\S​

跟 \s 唱反调,代表所有不是空白的字符。

​\A​

代表字符串的开始。

​\Z​

代表字符串的结束。

​^​

匹配字符串开始的位置。

​$​

匹配字符串结束的位置。

​.​

代表所有的单个字符,除了 \n \r

​[...]​

代表在 [] 范围内的字符,比如 [a-z] 就代表 a到z的字母

​[^...]​

跟 [...] 唱反调,代表不在 [] 范围内的字符

​ {n}​

匹配在 {n} 前面的东西,比如: o{2} 不能匹配 Bob 中的 o ,但是能匹配 food 中的两个o。

​{n,m}​

匹配在 {n,m} 前面的东西,比如:o{1,3} 将匹配“fooooood”中的前三个o。

​{n,}​

匹配在 {n,} 前面的东西,比如:o{2,} 不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。

​*​

和 {0,} 一个样,匹配 ​​* ​​前面的 0 次或多次。 比如 ​​zo*​​ 能匹配“z”、“zo”以及“zoo”。

​+​

和{1,} 一个样,匹配 + 前面 1 次或多次。 比如 zo+能匹配“zo”以及“zoo”,但不能匹配“z”。

​?​

和{0,1} 一个样,匹配 ?前面 0 次或 1 次。

​a|b​

匹配 a 或者 b。

​()​

匹配括号里面的内容。

知道了这些之后,我们怎么用 python 来进行判断呢?

那就要使用到 python 的库了re

re库

re.match

使用这个方法,主要传入两个参数

  • 第一个就是我们的匹配规则
  • 第二个就是需要被过滤的内容

例如,我们想要从

Xiaoshuaib has 100 bananas


拿到一个数字,那么我们就可以这样

import re

content = 'Xiaoshuaib has 100 bananas'
res = re.match('^Xi.*(\d+)\s.*s$',content)
print(res.group(1))


通过刚刚说的匹配符号 可以定义出相应的匹配规则

在这里我们将我们需要的目标内容用 () 括起来

此刻我们获得结果是

0

那么如果我们想要 100 这个数字呢?可以这样

import re

content = 'Xiaoshuaib has 100 bananas'
res = re.match('^Xi.*?(\d+)\s.*s$',content)
print(res.group(1))


看出区别了么 第二段代码我们多了一个 ?符号

在这里呢 涉及到两个概念

一个是贪婪匹配 另一个是非贪婪匹配

所谓贪婪匹配 就是我们的第一段代码 一个数一个数都要去匹配

而非贪婪呢我们是直接把 100 给匹配出来了

re.S

刚刚我们用到的​​.*?​​是我们在匹配过程中最常使用到的 表示的就是匹配任意字符

但是​​.*?​​的​​.​​代表所有的单个字符,除了​​ \n \r​

如果我们的字符串有换行了 怎么办呢?比如这样

content = """Xiaoshuaib has 100 
bananas"""


那么我们就需要用到 re 的匹配模式了

说来也简单 直接用 re.S 就可以了

import re

content = """Xiaoshuaib has 100
bananas"""
res = re.match('^Xi.*?(\d+)\s.*s$',content,re.S)
print(res.group(1))


re.search

可能有些朋友会觉得 匹配一个东西还要写开头结尾 有点麻烦

那么就可以使用 re 的另一个方法了:​​re.search​

它会直接去扫描字符串 然后把匹配成功的第一个结果的返回给你

import re

content = """Xiaoshuaib has 100
bananas"""
res = re.search('Xi.*?(\d+)\s.*s',content,re.S)
print(res.group(1))


这样子也是可以获取 100 的

re.findall

但是如果我们的内容是这样的

content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""


想要获取所有的 100 呢?

这时候就要用到 re 的另一个方法了

通过它我们就能轻松的获取所有匹配的内容了

import re

content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
res = re.findall('Xi.*?(\d+)\s.*?s;',content,re.S)
print(res)


这里的结果是

['100', '100', '100', '100']

re.sub

又有朋友觉得 如果我们想直接替换匹配的内容呢

就比如刚刚的字符串 可不可以把 100 直接替换成 250 呢?

那就要用到 re 的另一个方法了:​​re.sub​​可以这样

import re

content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
content = re.sub('\d+','250',content)
print(content)


那么结果就变成了

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

再来说说 re 的另一个常用到的方法吧

re.compile

这个主要就是把我们的匹配符封装一下

import re

content = "Xiaoshuaib has 100 bananas"
pattern = re.compile('Xi.*?(\d+)\s.*s',re.S)
res = re.match(pattern,content)

print(res.group(1))


其实和我们之前写的一样的

res = re.match('^Xi.*?(\d+)\s.*s$',content,re.S)


只不过 compile 一下 便于以后复用

关于 re 模块和正则表达式就介绍完啦