匹配单个字符
字符 |
功能 |
. |
匹配任意1个字符(除了\n) |
[ ] |
匹配[ ]中列举的字符 |
\d |
匹配数字,即0-9 |
\D |
匹配非数字,即不是数字 |
\s |
匹配空白,即 空格,tab键 |
\S |
匹配非空白 |
\w |
匹配单词字符,即a-z、A-Z、0-9、_ |
\W |
匹配非单词字符 |
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())
M
too
two
import re
# 大小写h都可以的情况
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())
h
Hello Python
7Hello Python
7Hello Python
7Hello Python
None
import re
ret = re.match("嫦娥\d号", "嫦娥1号发射成功")
print(ret.group())
ret = re.match("嫦娥\d号", "嫦娥2号发射成功")
print(ret.group())
ret = re.match("嫦娥\d号", "嫦娥3号发射成功")
print(ret.group())
嫦娥1号
嫦娥2号
嫦娥3号
匹配多个字符
字符 |
功能 |
* |
匹配前一个字符出现0次或者n次,即可有可无 |
+ |
匹配前一个字符出现1次或者n次,即至少有1次 |
? |
匹配前一个字符出现1次或者0次,即要么有要么没有 |
{m} |
匹配前一个字符出现m次 |
{m,n} |
匹配前一个字符出现从m到n次 |
- 实例演示:
*
匹配一个字符串,首字母大写,后面没有字符、或有小写字母
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())
M
Mnn
Aabcdef
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)
变量名 name1 符合要求
变量名 _name 符合要求
变量名 2_name 非法
变量名 __name__ 符合要求
- 实例演示:
?
匹配出0到99之间的数字
由于match
函数默认情况下,只要匹配到符合规则的字符串之后,就返回结果,所以当符合规则的字符串后有非法字符时,无法得到正确结果,需要使用$
来限制结尾字符
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())
7
33
0 # 这个结果并不是想要的,利用$才能解决
- 实例演示:
{m}
、{m, n}
匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线
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())
12a3g4
1ad12f23s34455ff66
i = ['neuedu@163.com', '123neu@163.com',
'neuedu@aa@163.com', 'neuedu@126.com',
'neuedu@163acom']
for s in i:
if re.match(r'[\w]{4,20}@163\.com', s) is None:
print('%s:格式错误' % s)
else:
print('%s:格式正确' % s)
匹配开头结尾
字符 |
功能 |
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
import re
# 不正确的情况
ret = re.match("[1-9]?\d", "09")
print(ret.group()) # 0
# 修正之后的
ret = re.match("[1-9]?\d$", "09")
if ret:
print(ret.group())
else:
print("不在0-99之间")
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)
xiaoWang@163.com 是符合规定的邮件地址,匹配后的结果是:xiaoWang@163.com
xiaoWang@163.comheihei 是符合规定的邮件地址,匹配后的结果是:xiaoWang@163.com
.com.xiaowang@qq.com 不符合要求
第2个地址被错误的当成了合法地址,通过添加结尾字符
来修正
ret = re.match("[\w]{4,20}@163\.com$", email)
匹配分组
字符 |
功能 |
(规则) |
将规则定义为一个分组 |
(规则1 | 规则2 ...) |
从多个规则中选择一个规则进行匹配 |
\组号 |
使用指定的分组进行匹配 |
(?P<别名> reg ) |
为规则分组起一个别名 |
(?P=别名) |
使用别名引用分组进行匹配 |
- 实例演示:
|
匹配出0-100之间的数字(注意 1位数、2位数表示形式的不同)
import re
ret = re.match("[1-9]?\d$|100", "8")
print(ret.group())
ret = re.match("[1-9]?\d$|100", "78")
print(ret.group())
ret = re.match("[1-9]?\d$|100", "100")
print(ret.group())
8
78
100
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邮箱
test@163.com
test@126.com
test@qq.com
不是163、126、qq邮箱
print(re.match('0[1-9]?\d{1,2}-[1-9][0-9]{6,7}', '024-12345678'))
<_sre.SRE_Match object; span=(0, 12), match='024-12345678'>
>>> import re
>>> ret = re.match("([^-]*)-(\d+)","010-12345678")
>>> ret.group()
'010-12345678'
>>> ret.group(1)
'010'
>>> ret.group(2)
'12345678'
- 课堂练习:匹配不是以4、7结尾的手机号码(11位)
import re
tels = ["13100001234", "18912344321", "10086", "18800007777"]
for tel in tels:
ret = re.match("1\d{9}[0-35-68-9]$", tel)
if ret:
print(ret.group())
else:
print("%s 不是想要的手机号" % tel)
13100001234 不是想要的手机号
18912344321
10086 不是想要的手机号
18800007777 不是想要的手机号
- 当某规则被重复使用时,可将其放与小括内,再使用时,用
\n
来引用
-
[a-z][0-9]{3}
这个规则使得3次,当第2次使用时,可以用\1
来替换
s = 'a123--a123==a123'
r = '[a-z][0-9]{3}--[a-z][0-9]{3}==[a-z][0-9]{3}$'
r = r'([a-z][0-9]{3})--\1==\1$'
print(re.match(r, s))
匹配出<html>hh</html>
import re
ret = re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>", "<html>hh</html>")
print(ret.group())
ret = re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>", "<html>hh</htmlbalabala>")
print(ret.group())
<html>hh</html>
<html>hh</htmlbalabala>
- 第2个匹配中,遇到了非正常的html格式字符串,匹配出错
- 正确的理解思路:如果在第一对<>中是什么,按理说在后面的那对<>中就应该是什么
# 通过引用分组中匹配到的数据即可,但是要注意是元字符串,即类似 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)
<html>hh</html>
<html>hh</htmlbalabala> 这是一对不正确的标签
- 字符串前面加上
r
表示原生字符串
,因为,正则表达式里使用\
作为转义字符,这就可能造成反斜杠困扰。
- 假如你需要匹配文本中的字符
\
,将需要4个反斜杠\
:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
- Python中使用原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观
>>> import re
>>> print(re.match('\\\\', '\\').group()) #未使用原义字符串
\
>>> print(re.match(r'\\', '\\').group())
import re
labels = ["<html><h1>www.neuedu.com</h1></html>",
"<html><h1>www.neuedu.com</html></h1>"]
for label in labels:
ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", label)
if ret:
print("%s 是符合要求的标签" % ret.group())
else:
print("%s 不符合要求" % label)
<html><h1>www.neuedu.com</h1></html> 是符合要求的标签
<html><h1>www.neuedu.com</html></h1> 不符合要求
import re
ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>",
"<html><h1>www.neuedu.com</h1></html>")
print(ret.group())
ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>",
"<html><h1>www.neuedu.com</html></h2>")
if ret:
print("%s 是符合要求的标签" % ret.group())
else:
print("不符合要求")
<html><h1>www.neuedu.com</h1></html>
不符合要求
- end -