目录
- Ⅰ, 正则表达式中的基本符号
- Ⅱ, 分组提取
- Ⅲ, 断言
- Ⅳ, re正则匹配
Ⅰ, 正则表达式中的基本符号
1, [] 匹配一组可能出现的字符
[Pp]ython 匹配 “Python” 或 “python”。
rub[ye] 匹配 “ruby” 或 “rube”。
[abcdef] 匹配中括号内的字母,如对"12345Pyyp"使用正则式[13Py]进行匹配,会匹配出12345Pyyp (加粗部分)
2, - 代表某个区间
[0-9] 匹配任何数字。类似于 [0123456789]。
[a-z] 匹配任何小写字母。
[A-Z] 匹配任何大写字母。
[a-zA-Z0-9] 匹配任何字母及数字。
3, \ 在正则中表示对特殊符号进行转义
对 - 进行转义表示为: \ - (\与-之间没有空格)
4, ^ 在[]内,表示取反;^ 在[]外,表示以什么为开头。
[^au] 除了au字母以外的所有字符。
[^0-9] 匹配除了数字外的字符
5, . 匹配除 “\n” 之外的任何1个字符。
要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。
6, ? 匹配一个字符出现0次或1次,另一个作用是非贪婪模式
如, u? 表示字符u可以出现1次或0次(不出现)
.? 表示匹配任一字符出现1次或0次
7, + 匹配1次或多次
.+ 表示任一字符至少出现1次
8, ** * 匹配0次或多次**
.+ 表示任一字符至少出现0次
9, \b 匹配单词的边界, 即单词和空格间的位置
如,对于字符串 hello world hi python hello code ,用正则表达式 \bhello\b 去匹配,会得到 hello world hi python hello code 这两个hello
10, \d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
11, \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
12, \w 匹配包括下划线的任何单词字符。等价于 [A-Za-z0-9_]。
\W 匹配任何非单词字符。等价于 [^A-Za-z0-9_] 。
13, {N} 表示在它之前的字符组出现N次
\d{5} 表示数字出现5次
{M,} 表示在它之前的字符组出现至少M次
{M,N} 表示在它之前的字符组出现M到N次
{1,} 等价于 +
{0,} 等价于 *
Ⅱ, 分组提取
1, () 可以实现分组
如,提取p标签<p>hello</p>
中的值hello: 使用 <p>(.*?)</p>
==>可提取出 hello
2, | 使用分组的同时还可以使用 | (or 或者)条件
如提取 “video.mp4 film.rmvb” 字符串的后缀名, (.avi|.mp4|.wmv|.rmvb)
3, (?:表达式) 非捕获组,从而不捕获数据(不提取该分组的数据),还能使用分组的功能
如匹配01-75855 12345-75855 tel:75855 --> 使用正则表达式 (?:\w+[\-|\:])(\d{5})
==> 不提取前面的字符,而只提取出75855
4, 分组的回溯引用,使用 \N 可以引用编号为N的分组。 如 \1 表示的就是第一个分组
如,匹配符合 ab ba 这种关系的单词: (\w)(\w).*?(\2)(\1)
(\2)为第二个分组,即第二个(\w),(\1)表示第一个分组(\w)
Ⅲ, 断言
1, 正向先行断言:(?=表达式),指在要匹配的某个字符串的位置向右看,表示所在位置右侧必须能匹配表达式
例如,给出字符串:
我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
如果要取出喜欢两个字,要求这个喜欢后面有你,这个时候就要这么写:喜欢(?=你)
,这就是正向先行断言
会匹配出:我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
2, 反向先行断言(?!表达式), 指要匹配的某个字符串位置的右边不能出现某字符。
例如: 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
如果要取出喜欢两个字,要求这个喜欢后面没有你,这个时候就要这么写:喜欢(?!你)
,这就是反向先行断言
会匹配出:我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
3,正向后行断言:(?<=表达式),指在某个位置向左看,表示所在位置左侧必须能匹配表达式
例如: 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
如果要取出喜欢两个字,要求喜欢的前面有我,后面有你,这个时候就要这么写:(?<=我)
喜欢(?=你)
4,反向后行断言:(?<!表达式),指在某个位置向左看,表示所在位置左侧不能匹配表达式
如果要取出喜欢两个字,要求喜欢的前面没有我,后面没有你,这个时候就要这么写:(?<!我)
喜欢(?!你)
★几个匹配的例子
1,匹配座机电话号码:
给出电话号码格式:
010-1234666 010-12347777 0321-1234666 0321-12347777
1.1 如果匹配所有符合上述格式的字符串
用正则式 (\d{3,4})-(\d{7,8})
可以把上述格式全部匹配
1.2 若果匹配xxx-xxxxxxx格式的字符串
对开头xxx前面与xxxxxxx后面加上边界,用正则式(\b\d{3})-(\d{7}\b)
可以匹配出来
1.3 若果匹配xxx-xxxxxxxx格式的字符串
用正则式(\b\d{3})-(\d{8}\b)
可以匹配出来
2,匹配手机号码:
给出电话号码格式:
13xxxxxxxxx
15xxxxxxxxx
18xxxxxxxxx
用正则式^1[358]\d{9}
可以匹配出来
3,匹配标签
给出csdn首页图标的链接,匹配出之间的数据:
字符串 <a href="javascript:void(0)" title="CSDN首页" class=""><img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo"></a>
。
用正则表达式来(?<=<a.*>)(<.*?>)(?=</a>)
匹配提取出 <img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo">
。
正则式 (?<=(<a.*>))(<.*?>)(?=</a>)
表示:第一个组(?<=(<a.*>))为要提取的数据左侧<>中a后面有0个及以上字符,第二个组表示要提取的数据0个或多个,第三个组为要提取的数据右侧是
Ⅳ, re正则匹配
re.findall(pattern, string, flags=0)
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
例如,还是匹配字符串 <a href="javascript:void(0)" title="CSDN首页" class=""><img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo"></a>
的之间的数据。
import re
ret = re.findall(r'<a.*?href="[^"]*".*?>(.*?)</a>','<a href="javascript:void(0)" title="CSDN首页" class=""><img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo"></a>')
print(ret) # ['<img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo">'] 列表形式
ret = re.findall(r'<a.*?href="([^"]*)".*?>(.*?)</a>','<a href="javascript:void(0)" title="CSDN首页" class=""><img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo"></a>')
print(ret) # [('javascript:void(0)', '<img src="//csdnimg.cn/cdn/content-toolbar/csdn-logo.png?v=20200416.1" class="csdn-logo">')]