正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串
正则表达式的作用
- 给定的字符串是否符合指定正则表达式的过滤逻辑,即匹配(例如Email地址检测,电话号码合法性判断等)
- 根据正则表达式从指定字符串中捕获特定的信息(例如从文章中获取所有含有a字母的单词)
- …
正则表达式的特点
- 灵活性、逻辑性、功能性非常强大
- 以极简的方式控制复杂的字符串
- 可读性差,对初学者晦涩难懂
- …
正则表达式语法(包括Python的专用扩展)
正则表达式由普通字符和元字符两大部分组成,而元字符相当于正则表达式的游戏规则,是其灵魂所在.因此,要掌握正则表达式在表达什么,最关键的就是要弄懂它的元字符的作用规则.
一般字符
.(点号)
匹配除了换行符之外的任意字符,在DOTALL模式下可以匹配换行符
例如:a.cd 匹配 abcd
\(反斜杠)
转义字符,它可能是最重要的元字符,一来它可以给后面的字符赋予特殊的意义,二来又能把元字符恢复原意
例如:\\匹配 \自身,\* 匹配 星号
[ ](方括号)
字符集合,匹配字符集包含的任意字符,字符集可以逐个列出([abcdefg]),也可以用区间表示([a-g]),如果第一个字符是^则表示一个负值字符集,意思就是匹配不包含本字符集的其他字符
例如:b[aiu]g 匹配 bag 、big 、 bug
预定义字符集
\d
匹配一个数字,等价于[0-9]
例如:a\db 匹配 a1b、a2b等
\D
匹配一个非数字字符,等价于[^0-9]
\s
匹配任何不可见字符,包括空格、制表符、换页符等等. 等价于[ \f\n\r\t\v]
例如:a\sc 匹配 a c
\S
匹配任何可见字符.等价于[^ \f\n\r\t\v]
\w
匹配单词字符和下划线. 等价于[a-zA-Z0-9_]
例如:a\wc 匹配 a1c , abc , aac , a9c, azc …
\W
匹配非单词字符.等价于[^a-zA-Z0-9_]
数量词
{n}
n为非负整数,匹配前面一个表达式n次
例如:a{2}c 匹配 aac 但不匹配 ac
{n,m}
n,m为非负整数,n<=m,匹配前面的一个表达式n至m次,其中n或m可以省略其中一个,n省略则匹配0~m次,m省略则匹配0~无限次
例如:a{1,3}c 匹配 ac、aac、aaac
*
匹配前面一个表达式0次或多次.等价于{0,}
例如:a*c 匹配 c、ac、aac、aaac、….
+
匹配前面一个表达式1次或无限次.等价于{1,}
例如:a+c 匹配 ac、aac…..
?
匹配前面一个表达式0次或1次.等价于{0,1}
例如:a?c 匹配 c 和 ac
*、+、?、{n,m}在Python中默认是贪婪的,即总是尝试匹配尽可能多,例如用 a\d+ 查找字符串 a1234abcd 则匹配到 a1234,而 ?可以使其变为非贪婪,即尽可能少匹配,例如用 a\d+? 查找字符串 a1234abcd 则匹配到 a1
边界匹配
^
匹配字符串的开头,或多行模式下匹配每一行的开头
例如:用 ^abc\d+ 查找 abc123abc456 将匹配到 abc123
$
匹配字符串的结尾,或多行模式下匹配每一行的结尾
例如:用 abc\d+$ 查找 abc123abc456 将匹配到 abc456
\A
匹配字符串的开头,在非多行模式下其实和^是一样的,在多行模式下它只会匹配全文的开头
\Z
匹配字符串的结尾,在非多行模式下其实和$是一样的,在多行模式下它只会匹配全文的结尾
\b
这是一个零宽界定符,不占任何位置,用于表示单词边界即词首或词尾
例如:用 \w+e\b 查找 english apple years 的结果是 apple
\B
这是一个零宽界定符,不占任何位置,用于表示非单词边界
例如:用 \w+e\w* 查找 english apple years 的结果是 apple 和 years
例如:用 \w+e\B\w* 查找 english apple years 的结果是 years
例如:用 \w+e\B 查找 english apple years 的结果是 ye
逻辑分组
|
将两个匹配条件进行逻辑“或”(Or)运算
例如:\w*b|\w*c 将匹配 字符串 “ abd acd ” 中的 ab 和 ac
(表达式)
括号内的表达式作为一个分组,一个正则表达式可以包含多个分组,从左至右分别用编号1,2,3…9表示各个分组,分组后可以接数量词*、+、?、{n}…等,另外表达式中的 | 只对分组内有效
例如:(abcd){3} 匹配 abcdabcdabcd
(?P<name>表达式)
命名分组,这是一个python扩展语法,它为分组指定了一个name的分组名
例如:(?P<id>abcd)
(?P=name)
对命名分组的逆向引用,即引用名为name的这个分组的匹配结果,这是一个python扩展语法
例如:(?P<age>\d+)Jack(?P=age) 匹配 19Jack19
\<number>
引用指定编号的分组匹配结果
例如:(\d+)abcd\1 匹配 10abcd10
特殊构造(不作为分组)
(?:表达式)
括号内的表达式不作为分组,没有分组编号,但可以后接数量词,表达式中可以有“或逻辑”
(?iLmsux)
iLmsux每个字符代表一种匹配模式,只能写在正则表达式的开头,可以同时选择多种匹配模式
例如:(?i)abc 忽略大小写,匹配 ABC 、aBC …
(?#…)
#后面…是注释内容
例如:\d+(?#number)abc 匹配 123abc
(?=表达式)
正向肯定预查,之后的字符必须要匹配表达式才能匹配成功,它不会消耗匹配的字符串,只作为肯定.
例如:windows(?=98|2000|xp|7) 可以匹配 windows2000 的 windows 并且2000这个字符串不会被消耗,但是不会匹配 windows8 的 windows.
(?!表达式)
正向否定预查,之后的字符必须要不匹配表达式才视为有效,它不会消耗匹配的字符串,只作为否定.
例如:windows(?!98|2000|xp|7) 可以匹配 windows8 的 windows 并且8这个字符串不会被消耗,但是不会匹配 windows2000 的 windows.
(?<=表达式)
反向肯定预查,与正向类似只是方向相反(我仿佛在逗你!)
例如:(?<=\d+)abc 匹配 前面是数字的abc
(?<!\d+)
反向否定预查,与正向类似只是方向相反
例如:(?<!\d+)abc 匹配 前面不是数字的abc
Python如何使用正则表达式
请参考我的另一篇文章 Python正则表达式的使用(re模块)