文章目录
  1. 1. 前言
  2. 2. 用法
    1. 2.1. 先compile后match
    2. 2.2. 直接匹配
    3. 2.3. match与search
    4. 2.4. 特殊符号
  3. 3. 正则表达式的规则
  4. 4. 字符串操作
  5. 5. reference

原载于CSDN,但维护起来不方便,就移过来了。

前言

发现自己在使用python的正则模块的时候,经常忘记具体的使用方法,搜索的话很快能得到解答,但过不了一阵就又忘记,而官方API文档有时候查找也是个麻烦。所以也就写个备忘,按照用途来归纳一下网上有的一些使用RE模块的经验。注意,本篇不讲述基本概念
首先当然是要

1
import re

用法

先compile后match

适用于模式需要多次使用

1
2
p = re.compile('ab*')# p:re.RegexObject
p.match("abbbb")#将返回一个 MatchObject

compile方法可以接受一些标志常量作为第二个参数,例如re.IGNORECASE
返回的MatchObject可以做进一步操作:

方法/属性 作用
group() 返回被 RE 匹配的字符串
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置

具体效果用一次就知道。

直接匹配

如果模式不需要多次使用,直接匹配即可:

1
re.match(patternString, text)#返回的是MatchObject

这些模块级函数的基本用法与RegexObject几乎一致,只是需要传入一个pattern参数,不再赘述。

match与search

只有在字符串的开头开始匹配,match才会返回MatchObject对象,而search则在全text中寻找匹配。例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
line = "Cats are smarter than dogs";

#No match!!
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print "match --> matchObj.group() : ", matchObj.group()
else:
print "No match!!"# if line="dogs are smarter than cats", things change

#search --> matchObj.group() : dogs
searchObj = re.search( r'dogs', line, re.M|re.I)
if searchObj:
print "search --> searchObj.group() : ", searchObj.group()
else:
print "Nothing found!!"

特殊符号

特殊符号主要是.,\,$,^等具有特殊意义的符号,这些符号的一般用法我不予介绍,在第2节的规则图中都有说明,本小节只介绍特殊用法。

'\'
反斜杠在正则表达式中用于转义。同时注意,在python的字符串中反斜杠同样用于转义,所以反斜杠会经过两层解释:python字符串解释,正则表达式解释。
这可能导致一些意料之外的问题,例如想在Latex文本中匹配\section,它作为RE表达式,需要写成'\\section'转义反斜杠,同时,如果它直接作为字符串参数传入RE模块,则还要分别对这两个反斜杠转义,写成'\\\\section',显然这不漂亮。
一种便捷的方式是使用raw字符,这可以免去字符串转义,写成r'\\section'。但是注意,这时候所有字符串中的特殊转义就无用了,r'\n'将被识别为一个'\'和一个'n'
另一种就是老老实实用compile。

'.'
点号,如果指定了 DOTALL 标记,匹配包括换行符在内的任意一个字符。

'^'
尖号,在MULTILINE 模式下,将匹配任意一个新行的开始。

'$'
dollar符号,匹配一个字符串的结尾或者字符串最后面的换行符,在MULTILINE模式下,匹配任意一行的行尾。也就是说,普通模式下,foo.$去搜索'foo1\nfoo2\n'只会找到'foo2',但是在 MULTILINE 模式,还能找到 'foo1',而且就用一个 $去搜索'foo\n'的话,会找到两个空的匹配:一个是最后的换行符,一个是字符串的结尾,演示:

1
2
3
4
5
6
>>> re.findall('(foo.$)', 'foo1\nfoo2\n')
['foo2']
>>> re.findall('(foo.$)', 'foo1\nfoo2\n', re.MULTILINE)
['foo1', 'foo2']
>>> re.findall('($)', 'foo\n')
['', '']

*?, +?, ??
'*''+''?'都是贪婪的,但这也许并不是我们所要的。可以在后面加个问号,将策略改为非贪婪,只匹配尽量短的RE。示例,体会两者的区别:

1
2
3
4
>>> re.findall('<(.*)>', '<H1>title</H1>')
['H1>title</H1']
>>> re.findall('<(.*?)>', '<H1>title</H1>')
['H1', '/H1']

{m,n}?
{m,n},也是贪婪的,a{3,5}如果有5个以上连续a的话,会匹配5个,这个也可以通过加问号改变。a{3,5}?如果可能的话,将只匹配3个a。
(?…)
这是一个表达式的扩展符号。’?’后的第一个字母决定了整个表达式的语法和含义,除了(?P…)以外,表达式不会产生一个新的组。如果需要指定匹配模式或者需要对匹配起别名以便提取,可以使用这个符号。

\b
匹配单词边界(包括开始和结束),这里的“单词”,是指连续的字母、数字和下划线组成的字符串。注意,\b的定义是\w和\W的交界,所以精确的定义有赖于UNICODE和LOCALE这两个标志位。

\B
和\b相反,\B匹配非单词边界。
\b\B零宽界定符(zero-width assertions)

前向界定符(lookahead assertion)
前向界定符也是一种零宽界定符(zero-width assertion)。前向界定符包括前向肯定界定符和前向否定界定符,如下所示:
(?=...)
前向肯定界定符。如果所含正则表达式(以 ... 表示)在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎并不会停止,模式的剩余部分还要尝试匹配界定符的右边。
(?!...)
前向否定界定符。与肯定界定符相反,当所含表达式不能在字符串当前位置匹配时成功,模式的剩余部分继续参与匹配。
文字描述可能不太好理解,看例子
要求匹配所有文件扩展名不为bat的文件,包括.ba,.batch等。

1
.*[.](?!bat$).*$

使用了前向否定界定,当bat$匹配失败时,当前位置不移动,继续匹配后面的表达式,当bat$匹配成功时,当前位置失败,停止匹配并返回。
前向否定的意思:在当前位置向前看(前向),如果表达式 bat$ 不会被匹配,尝试模式的其余部分(当做没有这个表达式,当前位置不变);如果 bat$ 匹配,整个模式将失败(否定)。后面的 $ 是为了确保象 “sample.batch” 这样以 “bat” 开头的扩展名会被允许。

正则表达式的规则

一图胜千言
规则图

字符串操作

RegexObject提供一些方法来对字符串进行操作。

方法/属性 作用
split(string [, maxsplit = 0]) 将字符串在 RE 匹配的地方分片并生成一个列表
sub(replacement, string[, count = 0]) 找到 RE 匹配的所有子串,并将其用一个不同的字符串替换
subn(replacement, string[, count = 0]) 与 sub() 相同,但返回新的字符串和替换次数

replacement中可以使用逆向引用,与正则匹配规则一样,字符串中的转义符号例如\n会被解释为对应的控制符,r'\n'则不会。
需要了解更多的方法可以查看官方文档

reference

比较详细Python正则表达式操作指南(re使用)
python正则表达式re模块详细介绍
Python正则表达式
Python正则表达式的七个使用范例
【循序渐进学Python】12.Python 正则表达式简介
Python doc
Python中使用正则表达式

文章目录
  1. 1. 前言
  2. 2. 用法
    1. 2.1. 先compile后match
    2. 2.2. 直接匹配
    3. 2.3. match与search
    4. 2.4. 特殊符号
  3. 3. 正则表达式的规则
  4. 4. 字符串操作
  5. 5. reference