python版
re模块
什么是正则表达式
正则表达式是由字符和特殊字符组成的字符串,它们描述了这些字符和字符的某种重复方式,能按照某种模式
匹配一系列有相似特征的字符串
正则表达式引擎
[A-Za-z]\w+,此正则表达式含义为:由大写字母A~Z或者小写字母a-z组成,后面至少跟一个由字母或数字组成的字符\w,举例如下:4xZ因为以数字开头,所以被过滤- 无特殊符号的正则表达式实例
正则表达式 | 文本内容 | |
---|---|---|
Python | python | |
abc999 | abc999 |
上述模式不包含任何特殊符号,它仅匹配自身所描述,所以只有字符串Python、abc999匹配此模式,正则表达式的强大之处在于特殊符号的应用,特殊符号定义了字符集合、自组匹配、模式重复次数,正是这些特殊符号使得一个正则表达式可以匹配字符串集合而不是一个字符串
- 正则表达式使用的特殊符号和字符
符号 | 说明 | 正则表达式样例 |
---|---|---|
literal | 匹配字符串 的值 | abc |
re1|re2 | 匹配正则表达式re1或re2 | abc|def |
. | 匹配任何字符(不包含换行符) | a. |
^ | 匹配字符串的开始 | ^idea |
$ | 匹配字符串的结尾 | /bin/*.sh$ |
* | 匹配前面出现的正则表达式0次或多次 | [A-Za-z0-9]* |
+ | 匹配前面出现的正则表达式1次或多次 | [a-z]+.com |
? | 匹配前面出现的正则表达式0次或1次 | go? |
{N} | 匹配前面出现的正则表达式N次 | [0-9]{3} |
{M,N} | 匹配前面出现的正则表达式M~N次 | [0-9]{3,5} |
[…] | 匹配字符组里出现的任意一个字符 | [aeiou] |
[..x-y..] | 匹配从x~y出现的任意一个字符 | [0-9],[A-Za-z] |
[^…] | 不匹配此字符集中出现的任何一个字符,包括某一范围的字符 | [aeiou],[A-Za-z0-9_] |
(* + ? {} )? | 用于上面出现的任何非贪婪,版本重复匹配次数符号 | .*?[a-z] |
(…) | 匹配封闭括号中的正则表达式(re),并保存为子组 | ([0-9]{3})?,f(oo|u)bar |
特殊字符(大写是小写的反义)
\d | 匹配任何数字,等同于[0-9],大写\D是\d反义,匹配任何非数字 | data\d+.txt |
---|---|---|
\w | 匹配任何数字字母字符,等同于[A-Za-z0-9_],\W是\w反义 | [A-Za-z_]\w+ |
\s | 匹配任何空白字符,等同于[\n\t\r\v\f] | of\sthe |
\b | 匹配单词边界 | \bThe\b |
\c | 逐一匹配特殊字符(即取消它的特殊含义,按字面匹配) | .,\,* |
\A(\Z) | 匹配字符串的开始(结束) | \ADear |
匹配(match)和搜索(search)的区别
匹配是尝试从整个字符串的开头进行匹配,而搜索则可以从一个字符串的任意位置开始匹配
贪婪模式与非贪婪模式区别举例
{m}:匹配的模式串重复m次
{m,n}:匹配的模式串至少重复m次,最多重复n次,如果没有m则等同于m=0,没有n则等同于n为无穷大。如a{,5}等同于a{0,5}表示a最多重复5次,可以一次也不出现。{m,n}这种匹配修饰符是贪婪模式的重复匹配,即尽可能按最大值n进行重复匹配。
{m,n}?:是{m,n}模式的非贪婪模式,即按最小值m进行重复匹配,其他与{m,n}相同。按最小值m进行重复匹配并不意味着n的值没有意义,当该修饰符后还有其他匹配模式子串时,为了支持后续子模式的匹配可能需要支持大于m次的匹配。
案例:
>>> re.search('[1-9]{2,10}','12345678abc') #贪婪模式匹配,将所有数字都匹配了
<re.Match object; span=(0, 8), match='12345678'>
>>> re.search('[1-9]{2,10}?','12345678abc') #非贪婪模式匹配,匹配最少量数字
<re.Match object; span=(0, 2), match='12'>
>>> re.search('[1-9]{2,10}?abc','12345678abc') #非贪婪模式匹配但要匹配完整模式因此将所有数字都匹配了
<re.Match object; span=(0, 11), match='12345678abc'>
>>> re.search('[1-9]{2,5}?abc','12345678abc') #非贪婪模式匹配,但为整体匹配按最大量匹配数字
<re.Match object; span=(3, 11), match='45678abc'>
>>>
字符和特殊字符内容讲解
管道符号匹配多个正则表达式模式(|)
它的含义是选择被管道符号分隔的多个不同的表达式的一个
引用场景,or的关系,多个字符串的匹配
正则表达式模式 | 匹配的字符串 |
---|---|
at|where | at,home |
how|are|you | how,are,you |
bat|bet|bit | bat,bet,bit |
- 匹配任意一个单个字符换行符除外(.)
正则表达式模式 | 匹配的字符串 |
---|---|
f.o | fao,f9o,f#o |
.. | 任意两个字符 |
.end | bend |
- 字符串的开头或结尾开始匹配
用这些字符匹配与前面描述的多数符号是不同的,因为这些字符指定了匹配字符的位置,正是这几个字符和
搜索位置有关,所以需要和搜索模式一起使用- 字符串开头匹配(^或\A)
- 字符串结尾匹配($或\Z)
正则表达式模式 | 匹配的字符串 |
---|---|
^from | 匹配任何以from开头的字符串 |
/bin/tcsh$ | 匹配任何以/bin/tcsh结尾的字符串 |
^subject:hi$ | 匹配仅由subject:hi组成的字符串 |
备注:若要匹配任何上述两个字符中的任意一个,必须用反斜杠进行转义
特殊字符\b,\B匹配单词边界,两者区别在于\b匹配的模式是一个单词边界,即与之对应的模式一定在一个单词的开头,不论这个单词前面有字符(该词在一个字符串的中间)还是没有字符(该单词在起始位置)
\B只匹配出现在一个单词的中间位置(即不在单词边界上的字符)
正则表达式模式 | 匹配的字符串 |
---|---|
the | 任何包含有the的字符串 |
\bthe | 任何以the开头的字符串 |
\bthe\b | 仅匹配the字符串 |
\Bthe | 任意包含the但不以the开头的字符串 |
创建字符类([])
需要匹配某些个字符,使用方括号的正则表达式会匹配方括号里的任意字符
正则表达式模式 | 匹配的字符串 |
---|---|
b[aou]t | bat、bot、but |
[cr] [23] [dp] [o2] | 包含4个字符的字符串,第一个是c或r,第二个是2或3,第三个是d或p,第四个是o或2 |
- 指定范围(-)和否定(^)
正则表达式模式 | 匹配的字符 |
---|---|
z.[0-9] | 字符z,后面跟一个任意字符,然后是0~9的数字 |
[r-u] [env-y] [us] | r~u中间任意字符+e、n、v、w、x、y中的任意一个字符,再后面是u或是s |
[^aeiou] | 非a、e、i、o、u字符 |
[^\t\n] | 除了tab制表符和换行符之外的任意一个字符 |
import re
if __name__ == '__main__':
pattern='z.[0-9]+'
target='z91291'
r=re.search(pattern,target)
if r is not None:
print(r.group())
else:
print('not match~!')
使用(*、+、?、{})实现多次出现和重复出现
表示出现左边的正则表达式0次或0次以上的情况
+表示出现左边的正则表达式至少一次的情况
?表示左边的正则表达式出现0次或1次的情况
{}可以是单值或两个值,如{N}表示匹配N次的情况,{M,N}表示匹配M到N次的情况
以上需要注意一点的是,这些符号前可以用反斜杠进行转义,使它们失去特殊作用,如将匹配号本身
?号有两种含义 1、单独出现时表示匹配出现0次或1次的情况
2、紧跟在表示重复的元字符后面时,表示要求搜索引擎匹配的字符串越短越好,例如(+?),越短越好的含
义是?当使用了表示重复的元字符(+?{m,n})时,正则表达式引擎在匹配时会尽量吸收更多的字符,这
叫做贪心。问号告诉正则尽可能偷懒,要求当前匹配消耗的字符越短越好
正则表达式模式 | 匹配的字符串 |
---|---|
[dn]ot? | 字符d或n,后面是个o,最后对多是一个t字符 |
0?[1-9] | 1~9中的任意一个数字,前面可能还有个0 |
[0-9]{15,16} | 15位或16位数字表示,例如信用卡 |
特殊字符表示
用\d代替0-9这个范围的十进制数字
用\w代替A-Za-z0-9_的整个字符数字的字符集
用\s代表空白字符
以上字符大写时表示反义
| 正则表达式模式 | 匹配的字符串 | | —- | —- | | \w+-\d+ | 至少一个数字或字母、紧跟-、然后至少一个数字 | | [A-Za-z]\w* | 第一个字母,如果存在的话第二个是字符 | | \d{3}-\d{3}-\d{4} | 例如800-555-1212 | | \w+@\w+.com | xxx@zzz.com |用圆括号建组
使用背景:有时我们也许对匹配的数据本身更有兴趣,我们不仅想知道是否整个字符串匹配我们的条件,还想在匹配成功时取出某个特定的字符串或子字符串
例如我们想用正则表达式\w+-\d+匹配一些内容,但又想把第一部分和第二部分的数字分别保存,如果我们给两个子模式都加上圆括号,即(\w+)-(\d+),那我们就可以对这两个匹配的子组分别进行访问了- re模块:核心函数和方法
- compile(pattern),对正则表达模式pattern进行编译
- match(pattern,string),用正则表达式pattern匹配字符串string,如果匹配成功返回一个匹配对象
- search(pattern,string),在string中搜索正则表达式pattern的第一次出现
- findall(pattern,string),在字符串string中搜索正则表达模式pattern的所有匹配的列表
- finditer(pattern,string)与上述类似,返回迭代器类型
- split(pattern,string)根据正则表达式pattern把字符串分割为一个列表,返回成功匹配的列表,最多分割max次
- sub(pattern,repl,string)把字符串中所有匹配正则表达式pattern的地方替换成字符串repl
- 匹配对象的方法
- group(num=0)返回全部匹配对象(指定编号是num的子组)
- groups()返回一个包含全部匹配的子组的元组
- group()方法返回所有匹配对象或是根据要求返回某个特定子组;groups()返回唯一或包含所有子组的元组;如果正则表达式没有子组的话,groups()将返回一个空元组,而group()仍会返回所有匹配对象
- match和search的区别,match尝试从字符串开头对模式进行匹配,而search不会
requests
bs4