python正则表达式

python使用正则表达式之前需要先倒入re模块

import re

可选标志位

re.A

ASCII,使得 \w,\W,\b,\B,\s 和 \S 只匹配 ASCII 字符,而不匹配完整的 Unicode 字符。这个标志仅对 Unicode 模式有意义,并忽略字节模式。

re.I

IGNORECASE,字符类和文本字符串在匹配的时候不区分大小写

re.L

LOCALE,使得 \w,\W,\b 和 \B 依赖当前的语言(区域)环境,而不是 Unicode 数据库

re.M

MULTILINE,通常 ^ 只匹配字符串的开头,而 $ 则匹配字符串的结尾。当这个标志被设置的时候,^ 不仅匹配字符串的开头,还匹配每一行的行首;& 不仅匹配字符串的结尾,还匹配每一行的行尾。

re.S

DOTALL,使 . 匹配包括换行符在内的所有字符

re.X

VERBOSE,这个标志使你的正则表达式可以写得更好看和更有条理,因为使用了这个标志,空格会被忽略(除了出现在字符类中和使用反斜杠转义的空格);这个标志同时允许你在正则表达式字符串中使用注释,# 符号后边的内容是注释,不会递交给匹配引擎(除了出现在字符类中和使用反斜杠转义的 #)。

可以同时使用多个标志位,方法:re.search( r'正则表达式', '字符串', re.M|re.I)

特殊字符

\d

匹配任何十进制数字;相当于类 [0-9]

\D

与 \d 相反,匹配任何非十进制数字的字符;相当于类 [^0-9]

\s

匹配任何空白字符(包含空格、换行符、制表符等);相当于 [ \t\n\r\f\v]

\S

匹配任何非空白字符;相当于类 [^\t\n\r\f\v]

\w

匹配字母数字及下划线

\W

匹配非字母数字及下划线

\b

匹配单词的开始或结束

\B

匹配非单词边界

元字符

|

或操作符,a | b匹配a或b

^

匹配字符串的开头,如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。

$

匹配字符串的末尾。如果设置了 MULTILINE 标志,就会变成匹配每一行的结束位置。

.

匹配任意单个字符,除了换行符,如果设置了DOTALL标志,则可以匹配包括换行符的任意字符。

[abc]

匹配括号中的a,b,c任意单个字符,而不是abc字符串

[^abc]

匹配除了a,b,c之外的任意字符

*

匹配前一个字符0次或多次

+

匹配前一个字符1次或多次

?

匹配前一个字符0次或1次

{n}

精确匹配前一个字符 n次,例如a{3}b,可以匹配aaab

{,n}

匹配前一个字符0次到n次

{n,}

匹配前一个字符 n次到无限次

{m,n}

匹配前一个字符 m 到 n 次

\1...\9

匹配第n个分组的内容。(abc)小括号括起来的为一组\1匹配第一个小括号的组...

1.compile函数:用于编译正则表达式,生成一个正则表达式对象

p = re.compile(r'正则表达式'[, 可选标志位])
p.search('待匹配内容').group() 

2.match函数:从字符串的起始位置开始匹配,如果起始位置匹配不成功返回none

re.match(r'正则表达式','字符串'[,可选标志位])  

匹配对象包含了很多方法和属性,以下几个是最重要的

group()返回匹配的字符串
start()返回匹配的开始位置
end()返回匹配的结束位置
span()返回一个元组表示匹配位置(开始,结束)

3.search函数:扫描整个字符串并返回第一个成功匹配的子串

re.search(r'正则表达式','字符串'[,可选标志位])  

匹配对象同样包含了很多方法和属性

group()返回匹配的字符串
start()返回匹配的开始位置
end()返回匹配的结束位置
span()返回一个元组表示匹配位置(开始,结束)

4.findall函数:扫描整个字符串,并返回一个列表,所有成功匹配的子串,如果没有匹配成功返回none

r = re.findall('\d+','111aaa222bbb333ccc')
print(r)
['111', '222', '333']
#当正则表达式加上括号时,返回结果会优先显示括号内匹配到的内容
#如果不想要优先显示括号内匹配到的内容,可以在括号内顶格加上?:
#(?:正则表达式)

5.finditer函数:和findall类似,成功匹配时返回一个迭代器

p = re.compile('\d+')
iterator = p.finditer('3只小甲鱼,15条腿,还有3条去了哪里?')
for match in iterator:
    print (match.group())

6.sub函数:替换,类似字符串的replace

>>> r = re.sub('\d+', 'b', 'aaa111aaa222aaa333')
>>> print(r)
aaabaaabaaab

7.split函数:切割

>>> r = re.split('\d+','111aaa222bbb333ccc') 
>>> print(r)
['', 'aaa', 'bbb', 'ccc']


#可以加上切割次数
>>> r = re.split('\d+','111aaa222bbb333ccc',1)
>>> print(r)
['', 'aaa222bbb333ccc']


#当需要显示切割的内容时,可以在正则表达式两边加上括号
#打印时会把切割的内容一并显示
>>> r = re.split('(\d+)','111aaa222bbb333ccc')
>>> print(r)
['', '111', 'aaa', '222', 'bbb', '333', 'ccc']

8.分组命名

定义分组:(?P<name>正则表达式)
分组引用:(?P=name)
>>> r = re.search('(?P<tag><\w+>)(?P<t>\w+)(?P=tag)','<h1>haha<h1>')
>>> print(r.group("t"))
haha
>>> print(r.group("tag"))
<h1>

  

  

  

贪婪 VS 非贪婪

当重复一个正则表达式时,如果使用 a*,那么结果是尽可能多地去匹配。当你尝试匹配一对对称的定界符,例如 HTML 标志中的尖括号,默认的贪婪模式会使得你很困扰。

我们来看下例子:

>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print(re.match('<.*>', s).span())
(0, 32)
>>> print(re.match('<.*>', s).group())
<html><head><title>Title</title>

RE 匹配在 <html> 的 < 后,.* 消耗掉字符串的剩余部分。由于正则表达式默认是贪婪的原因,RE 必须从字符串的尾部一个字符一个字符地回溯,直到找到匹配的 >。大家看到,按照这种方法,最后找到匹配内容竟是 <html> 的 < 开始,到</title> 的 > 结束。显然这不是你想要的结果。

在这种情况下,解决方案是使用非贪婪的限定符 *?、+?、?? 或 {m, n}?,尽可能地匹配小的文本。

>>> print(re.match('<.*?>', s).group())
<html>