1. re模块
1.1 re模块函数和方法
compile(pattern, flags=0)
-
-
使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象
match(pattern, string, flags=0)
-
-
尝试第一次使用带有可选标记的正则表达式的模式匹配字符串;
search(pattern, string, flags=0)
-
re模块函数和正则表达式对象方法 使用可选标记整体搜索字符串中出现的正则表达式模式;
-
-
如果匹配失败,就继续向后匹配;如果都没匹配成功,就返回None;
findall(pattern, string [, flags])
-
-
查找字符串中所有(非重复)出现的正则表达式模式,并返回一个匹配列表
finditer(pattern, string [, flags])
-
-
与findall()函数相同,但返回的是一个迭代器;对于每一次匹配,迭代器都返回一个匹配对象;
split(pattern, string [, max])
-
-
根据正则表达式的模式分隔符,split函数将字符串分割成列表,然后返回成功匹配的列表;
-
分割最多操作max次,默认分割所有匹配成功的位置;
sub(pattern, repl, string, count=0)
subn(pattern, repl, string, count=0)
-
-
使用repl替换所有正则表达式的模式在字符串中出现的位置;
-
-
用来替换的部分可以是一个字符串,也可以是一个返回字符串的函数;
purge()
group(num=0)
groups(default=None)
groupdict(default=None)
-
返回一个包含所有匹配的命名子组的字段,所有的子组名称作为字典的键;
-
1.2 常用的模块属性(用于大多数正则表达式函数的标记)
属性 |
描述 |
re.I, re.IGNORECASE |
不区分大小写的匹配; |
re.L, re.LOCALE |
根据所使用的本地语言环境通过该w,W,b,B,s,S实现匹配; |
re.M, re.MULTILINE |
^和$分别匹配目标字符串中行的起始和结尾,而不是严格匹配整个字符串本身的起始和结尾; |
re.S, re.DOTALL |
“.”点号通常匹配除了n之外的所有单个字符,该标记表示点号可以匹配全部字符; |
re.X, re.VERBOSE |
通过反斜杠转义,否则所有空格加上#(以及在该行中所有后续文件)都被忽略,除非在一个字符类中或者允许注释并且提高可读性; |
1.3 编译正则表达式
-
在模式匹配发生之前,正则表达式的模式必须编译成正则表达式对象。
-
由于正则表达式在执行过程中将进行多次比较操作,因此建议使用预编译;
-
-
由于预编译会被缓存,但是无法通过api确定已编译过的正则表达式的数据,所以使用purge()函数能够清除预编译的缓存;
1.4 上面说的函数和方法
-
几乎所有的re模块的函数,都可以作为regex对象(正则表达式对象)的方法。
-
-
-
-
-
2. 常用例子
compile()
#!/usr/bin/env python
import re
regx = re.compile("d+")
print type(regx)#<type '_sre.SRE_Pattern'>
s = regx.search("1o23helloworld")
print s.group()
匹配对象以及group()和groups()方法
-
当成功调用match()或者search()方法后,会返回一个对象,这个对象就是匹配对象;
-
匹配对象可以调用group()和groups()方法;
-
group():要么返回整个匹配对象,要么返回指定子组的特定子组;
-
groups():返回包含唯一或者全部子组的元组;如果没有子组的要求,当groups()仍然返回整个匹配时,groups()返回一个空元组;
match()匹配字符串
-
从字符串的起始位置开始匹配,当成功就返回一个匹配对象,否则就是None;
-
match()从起始位置开始匹配,当出现第一次失败后就整体失败;
#!/usr/bin/env python
import re
s="1o23hel45lowo54rld"
g = re.match("d+", s )
print g.group()
search()查找字符串
-
search()会扫描整个字符串,找到第一个匹配的字符串,然后返回一个匹配对象;
-
#!/usr/bin/env python
import re
s="kk1o23hel45lowo54rld"
g = re.search("d+", s )
print g.group()
findall()查找所有匹配的字串,返回一个元组
#!/usr/bin/env python
#encoding:utf-8
import re
r = re.findall("car","car")
print r # ['car']
r = re.findall("car","scary")
print r # ['car']
r = re.findall("car","carry the barcardi to the car")
print r # ['car', 'car', 'car']
r = re.findall("car","hello world")
print r # [] 空元祖
finditer()在匹配对象中迭代,返回一个元组
#!/usr/bin/env python
#encoding:utf-8
import re
s ="this and that"
r = re.findall(r"(thw+) and (thw+)", s, re.I)# re.I 不区分大小写, 字符串前面有r,防止转义
print r # [('this', 'that')]
print re.finditer(r"(thw+) and (thw+)", s, re.I).next().group()# this and that
print re.finditer(r"(thw+) and (thw+)", s, re.I).next().groups()# ('this', 'that')
print re.finditer(r"(thw+) and (thw+)", s, re.I).next().group(1)# this
print re.finditer(r"(thw+) and (thw+)", s, re.I).next().group(2)# that
print[g.groups()for g in re.finditer(r"(thw+) and (thw+)", s, re.I)]# [('this', 'that')]
重复、特殊字符以及分组
-
分组,在正则表达式中用圆括号进行分组,这样得到的匹配结果就是有分组的;
-
#!/usr/bin/env python
#encoding:utf-8
import re
r ="(www)-(ddd)"
m = re.match(r,"abc-123")
print m.group()# abc-123
print m.group(1)# abc 子组1
print m.group(2)# 123 子组2
print m.groups()# ('abc', '123') 全部子组
#!/usr/bin/env python
import re
m = re.match("(a(b))","ab")
print m.group()# ab
print m.group(1)# ab
print m.group(2)# b
print m.groups()# ('ab', 'b')
单个字符串中那个执行单个分组的多重匹配
#!/usr/bin/env python
#encoding:utf-8
import re
s ="this and that"
print re.findall(r"(thw+)", s, re.I)#['this', 'that']
r = re.finditer(r"(thw+)", s, re.I)
g = r.next()
print g.groups()# ('this',)
print g.group(1)# this
g=r.next()
print g.groups()# ('that',)
print g.group(1)# that
使用sub()和subn()搜索和替换
-
sub(pattern, repl, string, count=0)
-
subn(pattern, repl, string, count=0)
-
sub()和subn()都是讲某字符中所有匹配正则表达式的部分进行某些形式的替换;
-
用来替换的部分通常是一个字符串,也可以是一个返回字符串的函数;
-
-
但subn()还返回一个标识替换的总数;替换后的字符串和表示替换总数的数字一起作为一个拥有两个元素的元祖返回
#!/usr/bin/env python
#encoding:utf-8
import re
print re.sub("X","Mr. Smith","atttn: XnnDear X, n")
# atttn: Mr. Smith
# Dear Mr. Smit,
# 把atttn: XnnDear X, n中的X替换成Mr. Smith
print re.subn("X","Mr. Smith","atttn: XnnDear X, n")
# ('atttn: Mr. SmithnnDear Mr. Smith, n', 2)
# 返回的是替换后的字符和替换的个数组成的元组
# 把atttn: XnnDear X, n中的1个X替换成Mr. Smith
print re.sub("X","Mr. Smith","atttn: XnnDear X, n",1)
# atttn: Mr. Smith
# Dear X,
# 把atttn: XnnDear X, n中的1个X替换成Mr. Smith
print re.subn("X","Mr. Smith","atttn: XnnDear X, n",1)
# ('atttn: Mr. SmithnnDear X, n', 1)
在限定模式上使用split()分割字符串
-
如果分隔符不是特殊符号组成的正则表达式,re.split()与str.split()作用相同;
#!/usr/bin/env python
#encoding:utf-8
import re
print re.split(":","hello:world:china")# ['hello', 'world', 'china'] 返回的是列表
#!/usr/bin/env python
#encoding:utf-8
data =(
"Mountain View, CA 94000",
"sUNNYVALE, CA",
"Los Altos, 99999",
"Cupertino 98540",
"Palo Alto CA",
)
for datum in data:
print re.split(", |(?=(?:d{5}|[A-Z]{2}))", datum)
"""
['hello', 'world', 'china']
['Mountain View', 'CA 94000']
['sUNNYVALE', 'CA']
['Los Altos', '99999']
['Cupertino 98540']
['Palo Alto CA']
扩展符号
#!/usr/bin/env python
#encoding:utf-8
import re
print re.findall(r"(?i)yes", "yes, Yes, YES")
# ['yes', 'Yes', 'YES'] 扩展标记(?i)是忽略大小写
print re.findall(r"th.+","The first line, the second line, the third line")
# ['the second line, the third line']
print re.findall(r"(?s)th.+","The first line, the second line, the third line")
3. 匹配单个字符
字符 |
功能 |
. |
匹配任意1个字符(除了n) |
[ ] |
匹配[ ]中列举的字符 |
d |
匹配数字,即0-9 |
D |
匹配非数字,即不是数字 |
s |
匹配空白,即 空格,tab键 |
S |
匹配非空白 |
w |
匹配单词字符,即a-z、A-Z、0-9、_ |
W |
匹配非单词字符 |
匹配.
#coding=utf-8
import re
ret = re.match(".","M")
print(ret.group())
ret = re.match("t.o","too")
print(ret.group())
ret = re.match("t.o","two")
print(ret.group())
匹配[ ]
#coding=utf-8
import re
# 如果hello的首字符小写,那么正则表达式需要小写的h
ret = re.match("h","hello Python")
print(ret.group())
# 如果hello的首字符大写,那么正则表达式需要大写的H
ret = re.match("H","Hello Python")
print(ret.group())
# 大小写h都可以的情况
ret = re.match("[hH]","hello Python")
print(ret.group())
ret = re.match("[hH]","Hello Python")
print(ret.group())
ret = re.match("[hH]ello Python","Hello Python")
print(ret.group())
# 匹配0到9第一种写法
ret = re.match("[0123456789]Hello Python","7Hello Python")
print(ret.group())
# 匹配0到9第二种写法
ret = re.match("[0-9]Hello Python","7Hello Python")
print(ret.group())
ret = re.match("[0-35-9]Hello Python","7Hello Python")
print(ret.group())
# 下面这个正则不能够匹配到数字4,因此ret为None
ret = re.match("[0-35-9]Hello Python","4Hello Python")
# print(ret.group())
匹配d
#coding=utf-8
import re
# 普通的匹配方式
ret = re.match("嫦娥1号","嫦娥1号发射成功")
print(ret.group())
ret = re.match("嫦娥2号","嫦娥2号发射成功")
print(ret.group())
ret = re.match("嫦娥3号","嫦娥3号发射成功")
print(ret.group())
# 使用d进行匹配
ret = re.match("嫦娥d号","嫦娥1号发射成功")
print(ret.group())
ret = re.match("嫦娥d号","嫦娥2号发射成功")
print(ret.group())
ret = re.match("嫦娥d号","嫦娥3号发射成功")
print(ret.group())
4. 匹配多个字符
字符 |
功能 |
* |
匹配前一个字符出现0次或者无限次,即可有可无 |
+ |
匹配前一个字符出现1次或者无限次,即至少有1次 |
? |
匹配前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} |
匹配前一个字符出现m次 |
{m,n} |
匹配前一个字符出现从m到n次 |
匹配*
#coding=utf-8
import re
ret = re.match("[A-Z][a-z]*","M")
print(ret.group())
ret = re.match("[A-Z][a-z]*","MnnM")
print(ret.group())
ret = re.match("[A-Z][a-z]*","Aabcdef")
print(ret.group())
匹配+
#coding=utf-8
import re
names = ["name1", "_name", "2_name", "__name__"]
for name in names:
ret = re.match("[a-zA-Z_]+[w]*",name)
if ret:
print("变量名 %s 符合要求" % ret.group())
else:
print("变量名 %s 非法" % name)
匹配?
#coding=utf-8
import re
ret = re.match("[1-9]?[0-9]","7")
print(ret.group())
ret = re.match("[1-9]?d","33")
print(ret.group())
ret = re.match("[1-9]?d","09")
print(ret.group())
匹配{m}
#coding=utf-8
import re
ret = re.match("[a-zA-Z0-9_]{6}","12a3g45678")
print(ret.group())
ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66")
print(ret.group())
5. 匹配开头结尾
字符 |
功能 |
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
匹配$
#coding=utf-8
import re
email_list = ["xiaoWang@163.com", "xiaoWang@163.comheihei", ".com.xiaowang@qq.com"]
for email in email_list:
ret = re.match("[w]{4,20}@163.com$", email)
if ret:
print("%s 是符合规定的邮件地址,匹配后的结果是:%s" % (email, ret.group()))
else:
print("%s 不符合要求" % email)
6. 匹配分组
字符 |
功能 |
竖线| |
匹配左右任意一个表达式 |
(ab) |
将括号中字符作为一个分组 |
num |
引用分组num匹配到的字符串 |
(?P) |
分组起别名 |
(?P=name) |
引用别名为name分组匹配到的字符串 |
匹配|
#coding=utf-8
import re
ret = re.match("[1-9]?d","8")
print(ret.group()) # 8
ret = re.match("[1-9]?d","78")
print(ret.group()) # 78
# 不正确的情况
ret = re.match("[1-9]?d","08")
print(ret.group()) # 0
# 修正之后的
ret = re.match("[1-9]?d$","08")
if ret:
print(ret.group())
else:
print("不在0-100之间")
# 添加|
ret = re.match("[1-9]?d$|100","8")
print(ret.group()) # 8
ret = re.match("[1-9]?d$|100","78")
print(ret.group()) # 78
ret = re.match("[1-9]?d$|100","08")
# print(ret.group()) # 不是0-100之间
ret = re.match("[1-9]?d$|100","100")
print(ret.group()) # 100
匹配( )
#coding=utf-8
import re
ret = re.match("w{4,20}@163.com", "test@163.com")
print(ret.group()) # test@163.com
ret = re.match("w{4,20}@(163|126|qq).com", "test@126.com")
print(ret.group()) # test@126.com
ret = re.match("w{4,20}@(163|126|qq).com", "test@qq.com")
print(ret.group()) # test@qq.com
ret = re.match("w{4,20}@(163|126|qq).com", "test@gmail.com")
if ret:
print(ret.group())
else:
print("不是163、126、qq邮箱") # 不是163、126、qq邮箱
匹配
#coding=utf-8
import re
# 能够完成对正确的字符串的匹配
ret = re.match("<[a-zA-Z]*>w*</[a-zA-Z]*>", "<html>hh</html>")
print(ret.group())
# 如果遇到非正常的html格式字符串,匹配出错
ret = re.match("<[a-zA-Z]*>w*</[a-zA-Z]*>", "<html>hh</htmlbalabala>")
print(ret.group())
# 正确的理解思路:如果在第一对<>中是什么,按理说在后面的那对<>中就应该是什么
# 通过引用分组中匹配到的数据即可,但是要注意是元字符串,即类似 r""这种格式
ret = re.match(r"<([a-zA-Z]*)>w*</1>", "<html>hh</html>")
print(ret.group())
# 因为2对<>中的数据不一致,所以没有匹配出来
test_label = "<html>hh</htmlbalabala>"
ret = re.match(r"<([a-zA-Z]*)>w*</1>", test_label)
if ret:
print(ret.group())
else:
print("%s 这是一对不正确的标签" % test_label)
匹配number
#coding=utf-8
import re
labels = ["<html><h1>www.itcast.cn</h1></html>", "<html><h1>www.itcast.cn</h2></html>"]
for label in labels:
ret = re.match(r"<(w*)><(w*)>.*</2></1>", label)
if ret:
print("%s 是符合要求的标签" % ret.group())
else:
print("%s 不符合要求" % label)
匹配 (?P) (?P=name)
#coding=utf-8
import re
ret = re.match(r"<(?P<name1>w*)><(?P<name2>w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")
ret.group()
ret = re.match(r"<(?P<name1>w*)><(?P<name2>w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h2></html>")
ret.group()
7. 贪婪和非贪婪
-
-
-
-
-
在”*”,”?”,”+”,”{m,n}”后面加上?,使贪婪变成非贪婪
8. r的作用
>>> mm = "c:\a\b\c"
>>> mm
'c:\a\b\c'
>>> print(mm)
c:abc
>>> re.match("c:\\",mm).group()
'c:\'
>>> ret = re.match("c:\\",mm).group()
>>> print(ret)
c:
>>> ret = re.match("c:\\a",mm).group()
>>> print(ret)
c:a
>>> ret = re.match(r"c:\a",mm).group()
>>> print(ret)
c:a
>>> ret = re.match(r"c:a",mm).group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>