郑州网站排名服务,鑫灵锐做网站多少钱,wordpress菜单变英文,关键词搜索查询#x1f525; 交流讨论#xff1a;欢迎加入我们一起学习#xff01; #x1f525; 资源分享#xff1a;耗时200小时精选的「软件测试」资料包 #x1f525; 教程推荐#xff1a;火遍全网的《软件测试》教程 #x1f4e2;欢迎点赞 #x1f44d; 收藏 ⭐留言 #x1… 交流讨论欢迎加入我们一起学习 资源分享耗时200小时精选的「软件测试」资料包 教程推荐火遍全网的《软件测试》教程 欢迎点赞 收藏 ⭐留言 如有错误敬请指正 前言
我们在做接口自动化的时候处理接口依赖的相关数据时通常会使用正则表达式来进行提取相关的数据。
正则表达式又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(Regular Expression在代码中常简写为regex、regexp或RE) 。它是一个特殊的字符序列它能帮助你方便的检查一个字符串是否与某种模式匹配。在很多文本编辑器里正则表达式通常被用来检索、替换那些匹配某个模式的文本。而Python 自1.5版本起增加了re模块它提供 Perl 风格的正则表达式模式。
正则表达式语法
表示单字符
单字符即表示一个单独的字符比如匹配数字用\d匹配非数字用\D。
除以下语法也可以匹配指定的具体字符可以是1个也可以是多个。
字符功能说明.匹配任意1个字符除了\n[2a]匹配[]中括号中列举的字符如这里就是匹配2或者a这两个字符其中的一个\d匹配数字即0-9\D匹配非数字\s匹配空白即空格、tab键tab键为两个空格\S匹配非空白\w匹配单词字符即a-z、A-Z、0-9、_数字、字母、下划线\W匹配非单词字符
实例如下这里先说明一下findall(匹配规则要匹配的字符串)这个方法是查找所有匹配的数据以列表的形式返回后面会在re模块进行详解
python
import re# .匹配任意1个字符
re1 r.
res1 re.findall(re1, \nj8?0\nbth\nihb)
print(res1) # 运行结果[j, 8, ?, 0, b, t, h, i, h, b]# []匹配列举中的其中一个
re2 r[abc]
res2 re.findall(re2, 1iugfiSHOIFUOFGIDHFGFD2345a6a78b99cc)
print(res2) # 运行结果[a, a, b, c, c]# \d:匹配一个数字
re3 r\d
res3 re.findall(re3, dfghjkl32212dfghjk)
print(res3) # 运行结果[3, 2, 2, 1, 2]# \D:匹配一个非数字
re4 r\D
res4 re.findall(re4, d212dk\n$%3;]a)
print(res4) # 运行结果[d, d, k, , \n, $, %, ;, ], a]# \s匹配一个空白键或tab键tab键实际就是两个空白键
re5 r\s
res5 re.findall(re5,a s d a 9999)
print(res5) # 运行结果[ , , , , ]# \S: 匹配非空白键
re6 r\S
res6 re.findall(re6, a s d a 9999)
print(res6) # 运行结果[a, s, d, a, 9, 9, 9, 9]# \w匹配一个单词字符(数字、字母、下划线)
re7 r\w
res7 re.findall(re7, ce12sd#a as_#$)
print(res7) # 运行结果[c, e, 1, 2, s, d, a, a, s, _]# \W匹配一个非单词字符(不是数字、字母、下划线)
re8 r\W
res8 re.findall(re8, ce12sd#a as_#$)
print(res8) # 运行结果[, #, , #, $]# 匹配指定字符
re9 rpython
res9 re.findall(re9, cepy1thon12spython123python)
print(res9) # 运行结果[python, python]
表示数量
如果要匹配某个字符多次就可以在字符后面加上数量进行表示具体规则如下
字符功能说明*匹配前一个字符出现0次或者无限次即可有可无匹配前一个字符出现1次或无限次即至少1次?匹配前一个字符出现0次或1次即要么没有要么只有1次匹配前一个字符出现m次匹配前一个字符至少出现m次匹配前一个字符出现从m到n次
实例如下
python
import re# *表示前一个字符出现0次以上(包括0次)
re21 r\d* # 这里匹配的规则前一个字符是数字
res21 re.findall(re21, 343aa1112df345g1h6699) # 如匹配到a时属于符合0次但因为没有值所以会为空
print(res21) # 运行结果[343, , , 1112, , , 345, , 1, , 6699, ]# ? : 表示0次或者一次
re22 r\d?
res22 re.findall(re22, 343*a111)
print(res22) # 运行结果[3, , 4, 3, , , 1, 1, 1, ]# {m}:表示匹配一个字符m次
re23 r1[3456789]\d{9} # 手机号第1位为1第2位匹配列举的其中1个数字第3位开始是数字且匹配9次
res23 re.findall(re23,sas13566778899fgh256912345678jkghj12788990000aaa113588889999)
print(res23) # 运行结果[13566778899, 13588889999]# {m,}:表示匹配一个字符至少m次
re24 r\d{7,}
res24 re.findall(re24, sas12356fgh1234567jkghj12788990000aaa113588889999)
print(res24) # 运行结果[1234567, 12788990000, 113588889999]# {m,n}表示匹配一个字符出现m次到n次
re25 r\d{3,5}
res25 re.findall(re25, aaaaa123456ghj333yyy77iii88jj909768876)
print(res25) # 运行结果[12345, 333, 90976, 8876]
匹配分组
字符功能说明|匹配左右任意一个表达式(ab)将括号中字符作为一个分组
实例如下
python
import re# 同时定义多个规则只要满足其中一个
re31 r13566778899|13534563456|14788990000
res31 re.findall(re31, sas13566778899fgh13534563456jkghj14788990000)
print(res31) # 运行结果[13566778899, 13534563456, 14788990000]# ()匹配分组:在匹配规则的数据中提取括号里的数据
re32 raa(\d{3})bb # 如何数据符合规则结果只会取括号中的数据即\d{3}
res32 re.findall(re32, ggghjkaa123bbhhaa672bbjhjjaa45bb)
print(res32) # 运行结果[123, 672]
表示边界
字符功能说明^匹配字符串开头只能匹配开头$匹配字符串结尾只能匹配结尾\b匹配一个单词的边界单词字母、数字、下划线\B匹配非单词的边界
实例如下
python
import re# ^:匹配字符串的开头
re41 r^python # 字符串开头为python
res41 re.findall(re41, python999python) # 只会匹配这个字符串的开头
res411 re.findall(re41, 1python999python) # 因为开头是1,第1位就不符合了
print(res41) # 运行结果[python]
print(res411) # 运行结果[]# $:匹配字符串的结尾
re42rpython$ # 字符串以python结尾
res42 re.findall(re42, python999python)
print(res42) # 运行结果[python]# \b:匹配单词的边界单词即:字母、数字、下划线
re43 r\bpython # 即匹配python且python的前一位是不是单词
res43 re.findall(re43, 1python 999 python) # 这里第1个python的前1位是单词因此第1个是不符合的
print(res43) # 运行结果[python]# \B:匹配非单词的边界
re44 r\Bpython # 即匹配python且python的前一位是单词
res44 re.findall(re44, 1python999python)
print(res44) # 运行结果[python, python]
贪婪模式
python里数量词默认是贪婪的总是尝试匹配尽可能多的字符而非贪婪模式则是尝试匹配尽可能少的字符在表示数量的表达式后加上问号(?)就可以关闭贪婪模式。
如下例子匹配2个以上的数字如果符合条件它会一直匹配到不符合才停止如其中的34656fya34656符合2个数字以上那么它会一直匹配到6为止如果关闭贪婪模式那么在满足2个数字时就会停止最后可以匹配到34、65。
python
import re# 默认的贪婪模式下
test aa123aaaa34656fyaa12a123d
res re.findall(r\d{2,}, test)
print(res) # 运行结果[123, 34656, 12, 123]# 关闭贪婪模式
res2 re.findall(r\d{2,}?, test)
print(res2) # 运行结果[12, 34, 65, 12, 12]
re模块
在python中使用正则表达式就会用到re模块来进行操作提供的方法一般需要传入两个参数
参数1 匹配的规则参数2要进行匹配的字符串
re.findall()
查找所有符合规范的字符串以列表的形式返回。
python
import retest aa123aaaa34656fyaa12a123d
res re.findall(r\d{2,}, test)
print(res) # 运行结果[123, 34656, 12, 123]
re.search()
查找第一个符合规范的字符串返回的是一个匹配对象可以通过group()将匹配到的数据直接提取出来。
python
import res 123abc123aaa123bbb888ccc
res2 re.search(r123, s)
print(res2) # 运行结果re.Match object; span(0, 3), match123# 通过group将匹配到的数据提取出来返回类型为str
print(res2.group()) # 运行结果123
返回的匹配对象中span为匹配到的数据的下标范围match则是匹配到的值。
group()参数说明
不传参数获取的是匹配到的所有内容传入数值可以通过参数来指定获取第几个分组中的内容获取第1个分组传入参数1获取第2个分组传入参数2依次类推。
python
import res 123abc123aaa123bbb888ccc
re4 raaa(\d{3})bbb(\d{3})ccc # 这里分组就是前面说到的匹配语法()
res4 re.search(re4, s)
print(res4)
# group不传参数获取的是匹配到的所有内容
# group通过参数指定获取第几个分组中的内容获取第1个分组传入参数1获取第2个分组传入参数2依次类推..
print(res4.group())
print(res4.group(1))
print(res4.group(2))
re.match()
从字符串的起始位置进行匹配匹配成功则返回匹配到的对象如果开头的位置不符合匹配的规则不会继续往后面去匹配直接返回None。re.match()与re.search()都是只匹配一个不一样的是前者只匹配字符串的开头后者则是会匹配整个字符串但只获取第一个符合的数据。
python
import res a123abc123aaa1234bbb888ccc
# match只匹配字符串的开头开头不符合就返回None
res1 re.match(ra123, s)
res2 re.match(ra1234, s)
print(res1) # 运行结果re.Match object; span(0, 4), matcha123
print(res2) # 运行结果None
re.sub()
检索和替换用于替换字符串中的匹配项
re.sub()参数说明
参数1待替换的字符串参数2目标字符串参数3要进行替换操作的字符串参数4可以指定最多替换的次数非必填默认替换所有符合规范的字符串
python
import res a123abc123aaa123bbb888ccc
# font color#FF0000参数1/font待替换的字符串
# font color#FF0000参数2/font目标字符串
# font color#FF0000参数3/font要进行替换操作的字符串
# font color#FF0000参数4/font可以指定最多替换的次数非必填默认替换所有符合规范的字符串
res5 re.sub(r123, 666, s, 4)
print(res5) # 运行结果a666abc666aaa666bbb888ccc
用例参数化
在接口自动化测试中我们的测试数据都是保存在excel中的有些参数如果写死一个数据可能换个场景或者换个环境就不能用了那么切换环境时就需要先把新环境的测试数据准备好并且能支持去跑我们的脚本或者把excel的数据修改为适合新环境的测试数据维护的成本较高。因此就需要把我们的自动化脚本测试数据尽量地参数化降低维护成本。
我们先看简单版的参数化以登录为例登录时用到的账号、密码等信息都可以提取出来放到配置文件修改数据或更换环境时直接在配置文件中统一修改就可以了。
编辑 编辑
但如果有多个不同的数据需要参数化呢每个参数都加个判断去替换数据吗这样的代码既啰嗦又不好维护这时re模块就可以用上了直接看一个实例
python
import re
from common.myconfig import confclass TestData:用于临时保存一些要替换的数据passdef replace_data(data):r r#(.?)# # 注意这个分组()内的内容# 判断是否有需要替换的数据while re.search(r, data):res re.search(r, data) # 匹配出第一个要替换的数据item res.group() # 提取要替换的数据内容key res.group(1) # 获取要替换内容中的数据项try:# 根据替换内容中的数据项去配置文件中找到对应的内容进行替换data data.replace(item, conf.get_str(test_data, key))except:# 如果在配置文件中找不到就在临时保存的数据中找然后替换data data.replace(item, getattr(TestData, key))return data
注意这里的正则表达式是有使用?关闭贪婪模式的因为测试数据中可能会需要参数化2个或以上的数据如果不关闭贪婪模式它就只能匹配搭配一个数据举例如下
python
import redata {mobile_phone:#phone#,pwd:#pwd#,user:#user#}
r1 #(.)#
res1 re.findall(r1, data)
print(res1) # 运行结果[phone#,pwd:#pwd#,user:#user] 注意这里单引号只有一个数据
print(len(res1)) # 运行结果1r2 #(.?)#
res2 re.findall(r2, data)
print(res2) # 运行结果[phone, pwd, user]
print(len(res2)) # 运行结果3
另外提到的一个用于临时保存数据的类这里主要用于保存接口返回的数据因为有些测试数据是动态变化的可能要依赖于某个接口后面的测试用例又需要这些数据那么我们在接口返回时就可以保存到这个类里作为一个类属性接着在需要用这个数据的测试用例时把这个类属性提取出来替换到测试数据中即可。提示设置属性setattr对象, 属性名, 属性值获取属性值getattr(对象, 属性名)。 最后我邀请你进入我们的【软件测试学习交流群785128166】 大家可以一起探讨交流软件测试共同学习软件测试技术、面试等软件测试方方面面还会有免费直播课收获更多测试技巧我们一起进阶Python自动化测试/测试开发走向高薪之路 作为一个软件测试的过来人我想尽自己最大的努力帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源现在免费分享给大家有需要的小伙伴可以关注【公众号程序员二黑】自提