正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在Python中的一种微小的、高度专业化的编程语言。re模块提供来正则表达式匹配操作,用来对文本进行一些处理优化。匹配模式和被搜索的字符串既可以是Unicode字符串(str),也可以是8位字节串(bytes),不过两者不能混用。绝大多数正则表达式操作都提供了相应的函数,函数不需要先编译一个对象,但损失来一些优化参数。另外,第三方模块regex提供来与Python内置标准库re模块兼容的API接口,同时提供来额外的功能和更全面的Unicode支持。
正则表达式语法
正则表达式可以包含:普通字符、特殊字符、修饰符。
普通字符就是平常使用的绝大多数字符’ABC’、’0’等;特殊字符是既可以表示普通含义,也可以影响其左右字符或表达式的含义,如’(‘,’|’等;修饰符是指用来修饰表达式的字符,其中修饰字符中的重复修饰符(*
, +
, ?
, {m,n}
, 等)不能直接套用以此避免与其它修饰符产生的多义性,但可以使用括号来应用内层重复嵌套。
常用的特殊字符和修饰符
字符 | 含义 | ||
---|---|---|---|
. |
默认模式匹配除了换行的任意字符;如果指定了DOTALL标签,则可以匹配换行字符 | ||
^ |
默认模式匹配字符串开头;在MULTILINE模式下也会匹配换行后首个字符 | ||
$ |
匹配字符串尾或者换行符的前一个字符;在MULTILINE模式下匹配换行符的前一个字符 | ||
* |
对前面的正则表达式匹配0到任意次重复,如ab* 匹配的组合有a 、ab 、abb 或者其它a后面跟着n个b字符的组合 |
||
+ |
对前面的正则表达式匹配1到任意次重复,如同样是ab组合,ab+ 匹配的组合有ab 、abb 或者其它a后面跟着n个b字符的组合,但不会匹配a |
||
? |
对前面的表达式匹配0到1次重复,如ab? 会匹配a 、ab |
||
*? 、+? 、?? |
'*' , '+' ,和 '?' 修饰符都是重复修饰符,在字符串后面修饰符之后添加 ? 将使样式最小 方式进行匹配; 匹配的字符要尽量少,如 ab*? 会按照* 字符最小匹配次数0次进行匹配,也就是智能匹配a 这一种情况。 |
||
{m} |
对之前的正则表达式指定匹配m个重复,若少于m则不会匹配成功,如f{5} 只能匹配fffff , |
||
{m,n} |
对之前的正则表达式指定匹配m到n次匹配,在m到n之间尽可能多,如f{4,6} 则可能匹配的值有ffff 、fffff 、ffffff |
||
{m,n}? |
{m,n} 模式下匹配尽量少的字符,如对于ffffff 字符f{4,6}? 只匹配前四个 |
||
\ |
转义特殊字符;如果转义序列不被Python分析器识别,反斜杠和字符才能出现在字符串中,如果Python可以识别这个序列,那么反斜杠就要写两个 | ||
[] |
用于表示一个字符集合;字符在[] 可以单独列出,比如[ab] 匹配a 或者b ;通过用- 将两个数字连接表示字符范围,如[0-9] 表示匹配数字0到数字9之间的数字;特殊字符在集合中会失去它本来的匹配含义,如[+*] 只会匹配+ 或者* 字符;字符类如 \w 或者 \S (如下定义) 在集合内可以接受;不在集合范围内的字符可以通过取反来进行匹配,如果集合首字符是^ 则所有不在集合内的字符会被匹配,如[^8] 代表除了数字8之外将匹配所有的字符;若要在集合内匹配字符] 要么放在集合的首位字符,要么加反斜杠\ 进行转义 |
||
` | ` | 连接任意两个正则表达式,如A\ | B,将会匹配满足A表达式或满足B表达式的字符串 |
(...) |
匹配括号内的任意正则表达式,并标识出组合的开始和结尾 | ||
(?...) |
扩展类标记,'?' 后面的第一个字符决定了这个构建采用什么样的语法。 |
||
(?aiLmsux) |
(?…) 支持的扩展类型,( 'a' , 'i' , 'L' , 'm' , 's' , 'u' , 'x' 中的一个或多个) 这个组合匹配一个空字符串;这些字符对正则表达式设置以下标记 re.A (只匹配ASCII字符), re.I (忽略大小写), re.L (语言依赖), re.M (多行模式), re.S (点dot匹配全部字符), re.U (Unicode匹配), and re.X (冗长模式) |
||
(?:...) |
匹配在括号内的任何正则表达式,但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。 | ||
(?imsx-imsx:...) |
|||
(?P<name>...) |
(命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的 name 来获取的。组合名必须是有效的Python标识符,并且每个组合名只能用一个正则表达式定义,只能定义一次。 | ||
(?P=name) |
反向引用一个命名组合;它匹配前面那个叫 name 的命名组中匹配到的串同样的字串 | ||
(?#...) |
注释;里面的内容会被忽略。 | ||
(?=...) |
匹配 … 的内容,但是并不匹配除完全样式的内容。这个叫做 lookahead assertion。比如, Isaac (?=Asimov) 匹配 ‘Isaac ‘ 只有在后面是 ‘Asimov’ 的时候才会被匹配到。 | ||
(?!...) |
匹配 … 不符合的情况。这个叫 negative lookahead assertion (前视取反)。比如说, Isaac (?!Asimov)只有后面 不 是 ‘Asimov’ 的时候才匹配 ‘Isaac ‘ 。 | ||
(?<=...) |
匹配字符串的当前位置,它的前面匹配 … 的内容到当前位置。这叫:dfn:positive lookbehind assertion(正向后视断定) |
||
(?<!...) |
匹配当前位置之前不是 … 的样式。这个叫:dfn:negative lookbehind assertion (后视断定取非)。类似正向后视断定,包含的样式匹配必须是定长的。 |
||
`(?(id/name)yes-pattern | no-pattern)` | 如果给定的 id 或 name 存在,将会尝试匹配 yes-pattern ,否则就尝试匹配 no-pattern,no-pattern 可选,也可以被忽略。比如, (<)?(\w+@\w+(?:.\w+)+)(?(1)> |
反斜杠符号\与普通字符组成的特殊序列
由\
和字符组成的特殊序列情况,如果普通字符不是ASCII数位或者ASCII字母,正则表达式将匹配第二个字符,此外构成的特殊序列有:
特殊序列 | 含义 |
---|---|
\d |
匹配任何十进制数字,等价于[0-9] |
\D |
匹配任何非数字字符,等价于[^0-9] |
\s |
匹配任何空白字符,等价于[ \t\n\r\f\v] |
\S |
匹配任何非空白字符,等价于[^ \t\n\r\f\v] |
\w |
匹配任何字母与数字字符,等价于[a-zA-Z0-9_] |
\W |
匹配任何非字母与数字字符,等价于[^a-zA-Z0-9_] |
\A |
只匹配字符串开始 |
\Z |
只匹配字符串结束 |
\b |
匹配空字符串,但只在单词开始或结尾的位置。通常 \b 定义为 \w 和 \W 字符之间,或者 \w 和字符串开始/结尾的边界 |
\B |
匹配空字符串,但 不 能在词的开头或者结尾 |
正则表达式使用
re模块提供了API接口re.compile()
来将正则编译为对象,然后用来进行匹配。
示例代码:
>>> import re
>>> res = re.compile('ab+')
>>> res
re.compile('ab+')
其中re.compile()
也可以接收可选的flags参数,具体的参数值后面单独模块介绍
>>> res = re.compile('ab+', re.IGNORECASE)
re模块是Python附带的C扩展模块,正则被处理称为了字符串,并没有创建用于表达式正则的特殊语法。
反斜杠特别注意问题&解决方法
\
可以用来表示特殊形式或不调用特殊含义,又因为Python将正则表达式处理成来字符串来处理, 而反斜杠在普通的 Python 字符串里也有相同的作用,所以就产生了冲突。比如说要匹配一个字母上的反斜杠,其正则表达式要写成\\\\
,因为正则表达式力匹配一个反斜杠必须是\\
,而每个反斜杠在普通Python字符中也要写成\\
,所以造成如果正则表达式匹配一个反斜杠,必须要写成\\\\
的问题。
问题的解决办法是:对于正则表达式样式使用Python的原始字符串表示,使用字符前面带r
字符表示法用Python代码编写正则表达式。这么做的原因是在带有 'r'
前缀的字符串字面值中,反斜杠不必做任何特殊处理。 因此 r"\n"
表示包含 '\'
和 'n'
两个字符的字符串,而 "\n"
则表示只包含一个换行符的字符串。