re是python下内置的正则匹配模块。

0x00 规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.      元字符.表示匹配任何字符,除\n之外。
* 表示匹配前面的字符或分组0次或多次。
+ 表示匹配前面的字符或分组1次或多次。
? 表示匹配前面的字符或分组0次或1次。
{x} 表示匹配前面的字符或分组x次。
{x,y} 表示匹配前面的字符或分组x次至y次之间。

^ 表示匹配开始为^之后的。\A同样作用。
$ 表示匹配结束为$之前的。\Z同样作用

[abcd] 表示匹配其中的任意之一。
[1-9] 表示匹配1-9范围内的任意之一,也可以用[A-Z]、[a-z]、[0-9a-zA-Z]。
[^abc] 脱字符出现在[]中意义为‘非’,即不匹配其中的任何一个。也可用于范围[^1-9]、[^a-z]

\d 表示匹配任何一个十进制数字。与[0-9]等同。
\D 表示匹配任何一个非十进制数字。与[^0-9]等同。

\w 表示匹配任何一个十进制数字和字母。与[0-9a-zA-Z]等同。
\W 表示匹配任何一个除十进制数字和字母。与\w相反

\s 表示匹配任何一个空格字符。与[\n\t\r\v\f]等同。
\S 表示与\s相反。与[^\n\t\r\v\f]等同。

\b 表示匹配任何单词边界。边界即空白或非字母数字字符
\B 表示与\b相反。

| 表示‘或’,匹配其中之一。

0x01 转义

RE使用\来进行转义,而Python也使用\来进行转义,因此要进行双重的转义。
例如对\进行转义:

  • 首先RE先进行转义:\\
  • 然后Python也要对RE的两个\\转义:\\\\

也可以在字符串前面加r表示这是个Raw字符串。

0x02 RE全局方法

  • re.match(pattern,string,flag=)

    • 匹配从字符串开始就符合正则模式的字符串。
    • 匹配则返回匹配对象,否则返回none。
  • re.search(pattern,string,flag=)

    • 匹配第一个符合正则模式的字符串,即只匹配一次。
    • 匹配则返回匹配对象,否则返回none。
  • findall(pattern,string,flag=)

    • 将字符串中所有匹配的部分作为元素放入一个列表并返回。
  • finditer(pattern,string,flag=)

    • 与上面一个不同的是,将每次匹配得到的匹配对象放入一个迭代器中,最后返回一个迭代器,而不是列表。
    • 遍历迭代器时,每次返回一个匹配对象
  • sub(pattern,repl,string,count=)

  • subn(pattern,repl,string,count=)

    • 匹配模式的字符串部分用repl字符串替代,count指明次数,缺省替换匹配的所有。
    • subnsub区别在于,subn会返回新字符串及替换次数。
  • re.split(pattern,string,max=):用模式匹配的字符串作为分隔符,分割后返回的是一个列表。max表示最多分割的次数

  • re.compile(pattern):对模式进行编译,之后直接使用编译好的模式对象作为模式,对复杂任务效率更高。

    • 可以用re.compile()函数对正则模式字符串进行编译,并返回一个模式类对象:<class 're.Pattern'>
    • 模式类对象自己有match()search()findall()finditer()方法,方法使用与前面的全局方法一样。

上面的方法返回的匹配对象有如下方法:

  • group():返回匹配字符串。(其实默认传入0参数,意义为查看子组0)
  • start():返回匹配字符串的开始索引值。(也可以传入子组号)
  • end():返回匹配字符串的结束索引值。(也可以传入子组号)
  • span():返回匹配字符串的开始与结束索引到一个元组中(start,end)。(也可以传入子组号)

0x03 标志位(flag)

标志位:可以用全称或简写,如re.IGNORECASE等同于re.I,多个标志位|分开,如re.A|re.I。

1
2
3
4
5
re.ASCII             #\w、\s等转义字符只匹配ASCII符,仅对Unicode有效。
re.DOTALL/re.S #.可以匹配全部字符,包括换行符。
re.IGNORECASE/re.I #匹配时不区分大小写。
re.MULTILINE/re.M #^$将不止匹配字符串开头和结尾,还匹配每行的行首和行尾。
re.VERBOSE/re.X #模式的非转义字符的空格将会被忽略,可以用#进行注释。

0x04 分组

分组的作用

  • 方面一: 跟数学上的一样,被括号括起来后,方便使用*、+、?、{}进行操作。
  • 方面二: 可以对匹配字符串进行再操作、再匹配。

原理

  • 首先,分组的作用只具有数学上的,将正则模式去匹配字符串,得到匹配字符串,并放入子组0中。
  • 然后,再将每个分组作为模式去匹配第一次得到匹配字符串,得到的结果依次放入子组1,2,3….
    有多少对括号就有多少个子组,子组号按从左到右的’(‘统计。

group()与groups()

他们都是匹配对象的方法。

  • group():用于获取指定子组里的匹配字符串。

    • 正则模式匹配的匹配字符串放入子组0,且0是该方法的默认参数。
    • 分组匹配的匹配字符串依次放入1,2,3…..子组
    • 可以传入子组号查看指定子组的内容,且可以一次传入多个子组号,顺序也不要求。
  • groups():用于获取所有分组的匹配字符串,结果返回一个元组。

    • 只包含分组的匹配字符串,不包含正则模式匹配的匹配字符串。

若使用了findall()方法,返回的将不是匹配对象,而是列表对象。如果也使用了分组,那返回的列表的每个元素是分组匹配的,而不包含正则模式匹配的。

其他

  • 反向引用,在模式中可以用“[子组号]”来引用前面匹配成功的子组的匹配字符串。

  • 非捕获组:即让分组仅具有数学上意义,而不会再去匹配匹配字符串。

    • 通过在子组()中的最前面加:?: (如: a(?:\d)+b #\d将不会再作为模式去匹配)
  • 命名分组:可以给分组进行命名。

    • 通过在子组()中的最前面加:?P<[name]> (如:a(?P<fz1>\d)+b)命名后,group()方法可以通过名字也可以通过子组号。

断言

  • 前向肯定断言:如果此分组在此处匹配成功则成功,否则失败。(?=...) #...处是分组正则模式。
  • 前向否定断言:如果此分组在此处匹配成功则失败,否则成功。(?!...) #...处是分组正则模式。

0x05 非贪婪匹配

为非贪婪操作符,*+{}都是贪婪操作符(?有两重作用)。

通过在贪婪符之后加,表示让它们尽可能少的匹配。

即先让后面的匹配,自己再匹配,或者说自己尽可能少的匹配,别人尽可能多的匹配。

非贪婪匹配例子

如:    
    pattern1 = ‘.*(\d+)’   #贪婪匹配
    pattern2 = ‘.*?(\d+)’  #非贪婪匹配
    string=‘aa114321’

贪婪模式下:.*将匹配到aa114321,子组1匹配到1。(re.search(pattern1,string))

非贪婪模式下(*后面加):.*?匹配到aa,因为尽可能少匹配,反过来就是要让后面的尽可能多的匹配,因此子组匹配到114321。(re.findall(pattern2,string))

最后更新: 2019年05月21日 10:16

原始链接: https://sakuxa.com/2019/04/09/02python模块之re/