目录

  • Ⅰ, 正则表达式中的基本符号
  • Ⅱ, 分组提取
  • Ⅲ, 断言
  • Ⅳ, 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">')]