表示数量
匹配多个字符的相关格式
元字符 | 功能 |
---|---|
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现0次或者无限次,即可有可无 |
? | 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,} | 匹配前一个字符至少出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
示例1:
需求:匹配出,一个字符串第一个字母为大小字符,后面都是小写字母并且这些小写字母可有可无
import re
ret = re.match("[A-Z][a-z]*","Mm")
ret.group()
# 返回'Mm'
ret = re.match("[A-Z][a-z]*","Aabcdef")
ret.group()
# 返回'Aabcdef'
示例2:
需求:匹配出,变量名是否有效
import re
ret = re.match("[a-zA-Z_]+[\w_]*","name1")
ret.group()
# 返回'name1'
ret = re.match("[a-zA-Z_]+[\w_]*","_name")
ret.group()
# 返回'_name'
ret = re.match("[a-zA-Z_]+[\w_]*","2_name")
ret.group()
# 返回'None'
示例3:
需求:匹配出,0到99之间的数字
import re
ret = re.match("[1-9]?[0-9]","7")
ret.group()
ret = re.match("[1-9]?[0-9]","33")
ret.group()
ret = re.match("[1-9]?[0-9]","09")
ret.group()
示例4:
需求:匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线
import re
ret = re.match("[a-zA-Z0-9_]{6}","12a3g45678")
ret.group()
ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66")
ret.group(
表示边界
元字符 | 功能 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
\b | 匹配一个单词的边界 |
\B | 匹配非单词边界 |
示例1:
需求:匹配163.com的邮箱地址
import re
# 正确的地址
ret = re.match("[\w]{4,20}@163\.com", "[email protected]")
ret.group()
# 不正确的地址
ret = re.match("[\w]{4,20}@163\.com", "[email protected]")
ret.group()
# 通过$来确定末尾
ret = re.match("[\w]{4,20}@163\.com$", "[email protected]")
ret.group()
示例2:
示例3:
匹配分组
元字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P |
分组起别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
示例1:
需求:匹配出0-100之间的数字
import re
ret = re.match("[1-9]?\d","8")
ret.group()
ret = re.match("[1-9]?\d","78")
ret.group()
# 不正确的情况
ret = re.match("[1-9]?\d","08")
ret.group()
# 修正之后的
ret = re.match("[1-9]?\d$","08")
ret.group()
# 添加|
ret = re.match("[1-9]?\d$|100","8")
ret.group()
ret = re.match("[1-9]?\d$|100","78")
ret.group()
ret = re.match("[1-9]?\d$|100","08")
ret.group()
ret = re.match("[1-9]?\d$|100","100")
ret.group()
示例2:
需求:匹配出163、126、qq邮箱之间的数字
import re
ret = re.match("\w{4,20}@163\.com", "[email protected]")
ret.group()
ret = re.match("\w{4,20}@(163|126|qq)\.com", "[email protected]")
ret.group()
ret = re.match("\w{4,20}@(163|126|qq)\.com", "[email protected]")
ret.group()
ret = re.match("\w{4,20}@(163|126|qq)\.com", "[email protected]")
ret.group()
示例3:
需求:匹配出hh
# 能够完成对正确的字符串的匹配
ret = re.match("<[a-zA-Z]*>\w*[a-zA-Z]*>", "hh")
ret.group()
# 如果遇到非正常的html格式字符串,匹配出错
ret = re.match("<[a-zA-Z]*>\w*[a-zA-Z]*>", "hh")
ret.group()
# 正确的理解思路:如果在第一对<>中是什么,按理说在后面的那对<>中就应该是什么
# 通过引用分组中匹配到的数据即可,但是要注意是元字符串,即类似 r""这种格式
ret = re.match(r"<([a-zA-Z]*)>\w*\1>", "hh")
ret.group()
# 因为2对<>中的数据不一致,所以没有匹配出来
ret = re.match(r"<([a-zA-Z]*)>\w*\1>", "hh")
ret.group()
示例4:
需求:匹配出
www.neusoft.com
import re
ret = re.match(r"<(\w*)><(\w*)>.*\2>\1>", "www.neusoft.com
")
ret.group()
ret = re.match(r"<(\w*)><(\w*)>.*\2>\1>", "www.neusoft.com")
ret.group()
示例5:
需求:匹配出
www.neusoft.com
import re
ret = re.match(r"<(?P\w*)><(?P\w*)>.*(?P=name2)>(?P=name1)>", "www.neusoft.com
")
ret.group()
ret = re.match(r"<(?P\w*)><(?P\w*)>.*(?P=name2)>(?P=name1)>", "www.neusoft.com")
ret.group()
re模块的高级用法
search
需求:匹配出文章阅读的次数
import re
ret = re.search(r"\d+", "阅读次数为 9999")
ret.group()
findall
需求:统计出python、c、c++相应文章阅读的次数
import re
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print ret
sub 将匹配到的数据进行替换
需求:将匹配到的阅读次数加1
- 方法1:
import re
ret = re.sub(r"\d+", '998', "python = 997")
print ret
- 方法2:
import re
def add(temp):
strNum = temp.group()
num = int(strNum) + 1
return str(num)
ret = re.sub(r"\d+", add, "python = 997")
print ret
ret = re.sub(r"\d+", add, "python = 99")
print ret
练习 : 拉钩网
split 根据匹配进行切割字符串,并返回一个列表
需求:切割字符串“info:xiaoZhang 33 shandong”
import re
ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print ret
python贪婪和非贪婪
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'
>>>
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好。
>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'
>>>