python3爬虫-3.正则表达式与re库
常用表达式
字符 | 描述 |
---|---|
\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` |
() |
匹配括号里面的内容。 |
知道了这些之后,我们怎么用 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 模块和正则表达式就介绍完啦