正则表达式
最近学校布置了一个关于python爬虫的期末作业,而我之前对python爬虫一直都比较感兴趣但是没有系统的学过,就想借此机会开个新坑来系统学习和应用python爬虫,那我们开始吧
正则表达式在爬虫中扮演很重要的角色,几乎所有有关字符串的操作都可以使用正则表达式来完成,其可以帮助我们高效地从网页获取提取的信息.在正式接触爬虫之前是非常有必要的学习正则表达式,所有关于正则表达式的操作都使用 python 标准库中的 re 模块
元字符
元字符是正则表达式中具有特殊含义的字符,其用于构建更复杂的模式匹配规则
元字符 | 匹配内容 | 实例 |
---|---|---|
. | 匹配除换行符以外的任意单个字符 | 如a.b 可以匹配 aXb, a1b, a b |
\w | 匹配所有普通字符(数字、字母或下划线)→[a-z A-Z 0-9 _] | 如\w{3} 可以匹配abc,a1b,12_ |
\s | 匹配任意的空白符,包括空格,制表符,换页符等等 | 如\s{3} 可以匹配三个连续的空格 |
\d | 匹配数字→[0-9] | 如\d{3}可以匹配123,456 等等 |
\n | 匹配一个换行符 | |
\t | 匹配一个制表符 | |
\b | 匹配一个单词的结尾 | 如\bcat\b 匹配cat |
^ | 匹配字符串的开始位置,多行模式下匹配每一行的开始 | 如^abc 只能匹配abc 开头的字符串 |
$ | 匹配字符串的结尾位置,多行模式下匹配每一行的结束 | 如abc$ 只能匹配以abc 结尾的字符串 |
\W | 匹配非字母或数字或下划线→[^a-z A-Z 0-9 _] | 如\W{3} 可以匹配!!!,*** 等等 |
\D | 匹配非数字→[^0-9] | 如 \D{3} 可以匹配abc,xyz 等等 |
\S | 匹配非空白符 | \S{3} 可以匹配abc,123 等等 |
或运算符,匹配左边或右边的表达式 | ||
( ) | 正则表达式分组所用符号,匹配括号内的表达式,表示一个组。 | 如(ab)+ 可以匹配ab,ab,abab 等等 |
[...] | 匹配字符组中的字符 | 如[abc] 可以匹配a,b 或c |
[^...] | (否定字符集) 匹配除了字符组中字符的所有字符 | 如[^abc] 可以匹配除a,b,c 的所有字符 |
* | 匹配前面的子表达式0次或多次 | 如ab*c 可以匹配ac,abc,abbc 等等 |
+ | 匹配前面的子表达式1次或多次 | 如ab+c 可以匹配abc,abbc, 但不能直接匹配ac |
? | 匹配前面的子表达式0次或1次 | 如ab?c 可以匹配ac,abc ,不能匹配abbc |
匹配前面的子表达式恰好 n 次 | 如a{3} 只能匹配aaa |
|
匹配前面的子表达式至少 n 次 | 如a{2,} 可以匹配aa,aaa,aaaa 等等 |
|
匹配前面的子表达式至少 n 次,最多 m 次 | 如a{2,4} 可以匹配aa,aaa,aaaa, 但不能匹配aaaaa |
|
\ | 转义字符,用于匹配特殊字符 | 如\. 匹配字面上的. |
贪婪模式与非贪婪模式
在正则表达式中,贪婪模式与非贪婪模式是两种不同的匹配策略,都用于控制量词(
*,+,?,{}
)的行为
贪婪模式
-
默认情况下,大多数的量词都是贪婪的,贪婪模式会尽可能的多匹配字符,直到无法匹配
-
常见的贪婪量词:
*
:匹配前面的子表达式零次或多次+
:匹配前面的子表达式一次或多次?
:匹配前面的子表达式零次或一次{n}
:匹配前面的子表达式恰好 n 次{n,}
:匹配前面的子表达式至少 n 次- {
n,m}
:匹配前面的子表达式至少 n 次,最多 m 次
-
eg:假设一个字符串
"abcdadcde"
,使用贪婪模式匹配a.*e
pythonimport re text = "abcdadcde" pattern = re.compile(r'a.*e') match = pattern.search(text) print(match.group()) # 输出abcdadcde
- 在这个例子中,
.*
会尽可能多地去匹配字符,直到最后一个e
- 在这个例子中,
非贪婪模式
- 相比与贪婪模式,非贪婪模式会尽可能地少的去匹配字符,直到条件满足为止,非贪婪模式通过在量词后加上
?
来启用 - 常见的非贪婪量词
*?
:匹配前面的子表达式零次或多次,但尽可能少地匹配。+?
:匹配前面的子表达式一次或多次,但尽可能少地匹配。??
:匹配前面的子表达式零次或一次,但尽可能少地匹配。{n}?
:匹配前面的子表达式恰好 n 次,但尽可能少地匹配。{n,}?
:匹配前面的子表达式至少 n 次,但尽可能少地匹配。{n,m}?
:匹配前面的子表达式至少 n 次,最多 m 次,但尽可能少地匹配
eg:假设先有一个字符串"abcdeabcde"
,其匹配模式修改为a.*?e
python
import re
text = "abcdeabcde"
pattern = re.compile(r'a.*?e')
match = pattern.search(text)
print(match.group()) # 输出abcde