1.正则表达式的匹配规则
符号 含义
. 匹配除换⾏符以外的任意字符
\w 匹配字⺟或数字或下划线
\s 匹配任意的空⽩符
\d 匹配数字
\n 匹配⼀个换⾏符
\t 匹配⼀个制表符
\W 匹配⾮字⺟或数字或下划线
\S 匹配⾮空⽩符
\D 匹配⾮数字
^ 匹配字符串的开始
$ 匹配字符串的结尾
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示⼀个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
量词:控制前面的元字符出现的次数
* 重复0次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
贪婪匹配和惰性匹配
.* 贪婪匹配
.*? 惰性匹配
例子:
匹配正整数 ^+ [1-9]\d$
2.re解析
1)findall 匹配字符串中所有符合正则内容,返回list
2)finditer和findall 差不多,匹配字符串中所有的内容,只不过返回的是迭代器,从迭代器中拿到内容需要通过.group()获取
import re
it = re.finditer(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
print(it)
# <callable_iterator object at 0x00000200F5DBF5C8>for i in it: print(i)# <re.Match object; span=(7, 12), match='10086'># <re.Match object; span=(23, 28), match='10010'>
it = re.finditer(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
for i in it:
print(i.group()) # 10086# 10010
3)search找到一个结构就返回,返回的结构是match对象。如果匹配不是search返回的是None。拿数据也需要通过group()
import res = re.search(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
print(s) # <re.Match object; span=(7, 12), match='10086'>print(s.group()) # 1008
4)match 从字符串的开头匹配
import re
s = re.match(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
print(s.group()) # AttributeError: 'NoneType' object has no attribute 'group'
5)compile()可以将⼀个⻓⻓的正则进⾏预加载,⽅便后⾯的使⽤
obj = re.compile(r"\d+")
ret = obj.finditer("我的电话号是:10086, 我女朋友的电话是:10010")
for it in ret:
print(it.group())
6)正则中的内容如何单独提取?
单独获取到正则中的具体内容可以给分组起名字。(?P<分组名字>正则)
扩展:
在正则表达式中,?P 是用于 命名捕获组 的语法,主要出现在 Python 的 re 模块中。它的作用是为一个捕获组(group)指定一个名称,方便后续通过名称(而非数字索引)引用匹配的内容。
import re
s = """<div class='⻄游记'><span id='10010'>中国联通</span></div>"""
obj = re.compile(r"<span id='(?P<id>\d+)'>(?P<name>\w+)</span>", re.S)
result = obj.search(s)
print(result.group()) # 结果: <span id='10010'>中国联通</span>
print(result.group("id")) # 结果: 10010 # 获取id组的内容print(result.group("name")) # 结果: 中国联通 #获取name组的内容
3.re模块练习
扩展:re.finditer() 返回的是一个 一次性迭代器(类似一次性筷子),遍历完第一次后,第二次再遍历就是空的。
扩展:r'<strong class="rank">(?P<score>.*?)</strong>.*?'r'<a href=\'/\d+/\'>(?P<type>.*?)</a>' ;这种写法是需要这两个标签在HTML中并不是连续的的
正则表达式
总结:
1.findall直接返回所有的列表,ffinditer更节省内存(适合大数据)
2.search和match的区别:match必须从头开始匹配
3.分组名(?P<name>...)能清晰的提取复杂的正则中的部分内容
4.正则规则中(如\d、\w)是核心,需要结合量词灵活使用