0x01:正则表达式是啥子嘛

正则表达式(简称 Regex)是一些字符和特殊符号组成的字符串,它们描述了模式的重复或者表述多个字符。正则表达式可以按照某种模式匹配一系列有相似特征的字符串。

在Python 术语中,主要有两种方式完成模式匹配: “搜索”(search),即在字符串的任意部分中搜索匹配的模式;而 “匹配” (matching)是指 判断一个字符串能否从起始处或者部分地匹配的模式。 搜索通过 search()函数或方法来实现,而匹配通过调用 match() 函数或方法来实现。

0x02:常见的正则表达式符号和特殊字符

表示法 描述 正则表达式示例
符号
re1 | re2 匹配正则表达式 re1或者re2 foo | bar
. 匹配任何字符(除了\n 以外) b.b
^ 匹配字符串的起始部分 ^Dear
$ 匹配字符串终止部分 /bin/*sh$
* 匹配0次或者多次前面出现的正则表达式 [A-Za-Z0-9]*
+ 匹配1次或者多次前面出现的正则表达式 [a-z]+\.com
匹配0次或者1次前面出现的正则表达式 goo?
{N} 匹配N次前面出现的正则表达式 [0-9]{3}
{M,M} 匹配M~N次前面出现的正则表达式 [0-9]{5,9}
[…] 匹配来自字符集的任意单一字符 [aeiou]
[…x-y…] 匹配 x-y 范围中的任意单一字符 [0-9],[A-Za-z0-9]
[^…] 不匹配次字符集出现的任何一个字符,包括某一范围的字符(如果此字符集中出现) [^aeiou],[^A-Za-z0-9]
(*|+|?|{})? 用于匹配上面频繁出现\重复出现符号的非贪婪版本( *、+、?、{}) .*?[a-z]
(…) 匹配封闭的正则表达式,然后另存为子组 ([0-9]{3})? , f(oo|u)bar
表示法 描述 正则表达式示例
特殊字符
\d 匹配任何十进制数字,于[0-9]一致(\D 与 \d相反,不匹配任何非数值型的数字) data\d+.txt
\w 匹配任何字母数字字符,与[A-Za-z0-9_]相同(\W与之相反) [A-Za-z_]\w+
\s 匹配任何空格字符,与[\n\t\r\v\f]相同 (\S与之相反) of\sthe
\b 匹配任何单词边界(\B与之相反) \bthe\b
\N 匹配已保存的子组N(参见上面的(…)) price:\16
\c 逐字匹配任何特殊字符c \. , \\ ,\*
\A(\Z) 匹配字符串的其实(结束) \ADear
表示法 描述 正则表达式示例
扩展表示法
(?iLmsux) 在正则表达式中嵌入一个或多个特殊“标记”参数(或者通过函数 \ 方法) (?x) ,(? im)
(?:…) 表示一个不用保存的分组 (?:\w+\.)*
(?p…) 像一个仅由name表述而不是数字ID表述的正则分组匹配 (?)
(?p=name) 在同一字符串中匹配由 (?p<name)分组的之前文本 (?=data)
(?#…) 表示注释,所有内容被忽略 (?#comment)
(?=…) 匹配条件是如果 … 出现之后的位置,而不使用输入字符串:称作正向前视断言 (?=.com)
(?!…) 匹配条件是如果 … 不出现之后的位置,而不使用输入字符串:称作负向前视断言 (?!.net)
(?<=…) 匹配条件是如果 … 出现之前的位置,而不使用输入字符串:称作正向后视断言 (?<=800-)
(?<=…) 匹配条件是如果 … 出现之前的位置,而不使用输入字符串:称作负向后视断言 (?<!192\.168\.)
(?(id\name)Y|N) 如果分组所提供的id或者 name 名称存在,就返回正则表达式的条件匹配Y,如果不存在,就返回N; |N 是可选项 (?(1)y|x)

0x03:使用则一匹配符号匹配多个正则表达式模式

表示 则一匹配的管道符号 (|),表示从 一个 “ 从多个模式中选择其一”的操作。用于分割不同的正则表达式。

正则表达式模式 匹配的字符串
at | home at 、 home
bat | bet | bit bat、bet、bit

0x04:匹配任意单个字符

点号或者句点(.) 符号匹配除了换行符 \n 以外的任何字符。

正则表达式模式 匹配的字符串
f.o 匹配在字母 f 和 o 之间的任意一个字符:例如 fao 、f9o、f#o等
.. 任意两个字符
.end 匹配在字符串end 之前的任意一个字符

0x05:从字符串的起始或者结尾或者单词边界匹配

正则表达式模式 匹配的字符串
^from 任何以from作为起始的字符串
/bin/bash$ 任何以/bin/bash作为结尾的字符串
^Subject:hi$ 任何由单独的字符串Subject:hi构成的字符串

特殊字符 \b 和 \B 可以用来匹配字符边界。而两者的区别在于 \b 将用于匹配一个单词的 边界,这意味着如果一个模式必须位于单词的起始部分,就不管该单词前面(单词位于字符串中间)是否有特殊字符(单词位于行首)。\B 将匹配出现在一个单词中间的模式(即,不是单词边界)。

正则表达式模式 匹配的字符串
the 任何包含the的字符串
\bthe 任何以the 开始的字符串
\bthe\b 进匹配单词 the
\Bthe 任何包含但并不以the作为起始的字符串

0x06: 创建字符集

如果某些时候,我们想匹配某些特定的字符,就可以使用方括号,该正则表达式能够匹配一对方括号中包含的任何字符。

正则表达式模式 匹配的字符串
b[aeiu]t bat、bet、bit、but
[cr][23][op] 一个包含三个字符的字符串,第一个字符是 c 或 r,然后是 2 或 3 ,后面是 o 或者 p。例如 c20、c3p、r2o、r3p

0x07: 限定范围和否定

除了单字符以外,字符集还支持匹配指定的字符范围。方括号中两个符号中间用连字符 (-) 连接,用于指定一个字符的范围。如果脱字符 (^) 紧跟在左方括号后面,这个符号表示不匹配给定字符集中的 任何一个字符。

正则表达式模式 匹配的字符串
z.[0-9] 字母 z 后面跟着任何一个字符,然后跟着一个数字
[r-u][env-y][us] 字母 r 、s、t 或者 u 后面跟着 e、n、v、w、x、或者y ,然后跟 u 或者 s
[^aeiou] 一个非元音字符
[^\t\n] 不匹配制表符 或者 \n
[“-a] 在一个ASCII系统中,所有字符位于 “ 和 a之间,即34-97之间

0x08:使用闭包操作符实现存在性和频数匹配

特殊符号 、+ 和 ? 所有 的这些都可以用于匹配一个、多个或者没有出现的字符串模式。星号或者星号操作符()将匹配其左边的正则表达式出现0此或者多次的情况(该操作叫做闭包)。 加号(+)操作符将匹配一次或者多次出现的正则表达式, 问号(?)操作符将匹配零次或者一次出现的正则表达式。

还有大括号操作符 {} , 里面或者单个值或者是由一对逗号分隔的值。这将匹配前面的正则表达式 N 次(如果是 {N} 或者一定范围的次数; 例如 {M,N} 匹配M -N 次出现,这些符号能够由 反斜线符号进行转义: *匹配星号,等等。

正则表达式模式 匹配的字符串
[dn]ot? 字母 d 或者 n 后面跟一个 o,然后是最多一个t , 例如do、no、dot、not
0?[1-9] 任何数值数字,它可能前置一个0,例如,匹配一系列从 1-9 月的数值
[0-9]{15,16} 匹配15或16个数字(例如信用卡号码)
</?[^>]+> 匹配全部有效的(和无效的)HTML标签

0x09:表示字符集的特殊字符

我们还可以使用 d 匹配任何十进制数字。另外一个 特殊字符 \w 能够表示全部字母数字的字符集,相当于[A-Za-z0-9]的缩写形式, \s 可以 用来表示空格字符。

正则表达式模式 匹配的字符串
\w+-\d+ 一个由字母数字组成的字符串和一个连字符分隔的数字
[A-Za-z]\w* 第一个字符是字母,其余字符(如果存在) 可以是数字或者字母
\w+@\w+\.com 以 XXX@YYY.com格式表示简单的电子邮件地址

0x10: 使用圆括号指定分组

想要知道能否提取任何已经成功匹配的特定字符串或者子字符串, 可以使用一对 圆括号 包裹任何正则表达式。

当使用正则表达式时,一对圆括号可以实现一下任意一个(或者两个)功能:

  • 对正则表达式进行分组;
  • 匹配子组
正则表达式模式 匹配的字符串
\d+(\.\d*)? 表示浮点数的字符串,例如 0.004

0x11: 扩展表示法

正则表达式模式 匹配的字符串
(?:\w+\.)* 以 句点多为结尾的字符串,但是这些 匹配不会保存下来
(?=.com) 如果一个字符串后面跟着 .com 才做匹配操作,并不使用任何目标字符串
(?!.net) 如果一个字符串不后面跟着 .net 才做匹配操作
(?<=800-) 如果一个字符串之前为 800- 才做匹配操作,假定为电话号码,同样,不适用任何输入字符串
(?<192\.168\.) 如果一个字符串之前不是 192.168. 才做匹配
(?(1)x|y) 如果匹配组(1)存在,就与 y 匹配,否则 ,就与 x 匹配