概述
JMeter包含模式匹配软件Apache Jakarta ORO,在Jakarta 网站上有一些文档,例如关于 模式匹配字符的总结,也有关于 OROMatcher用户指南的文档。
模式匹配非常类似于Perl中的模式匹配。Perl的完整安装将包括大量关于正则表达式的文档——查找perlrequick,perlretut,perlre 和 perlreref。
值得强调的是”contains”和”matches”之间的区别,就像在响应断言中所使用的那样:
“contains”意味着正则表达式至少匹配目标的某些部分,因此 ‘alphabet’ “contains” ‘ph.b.’ 因为正则表达式与子字符串的”phabe”匹配。
“matches”意味着正则表达式与整个目标匹配。因此,”alphabet”是由”al.*t”匹配的。
在这种情况下,它等价于将正则表达式包装在^和$中,也就是 ‘^al.*t$’。
然而,情况并非总是如此。例如,正则表达式 ‘alp|.lp.*’里contains着”alphabet”,但里没有matches ‘alphabet’。
为什么?因为当模式matcher在”alphabet”中找到序列”alp”时,它就会停止尝试任何其他的组合,而”alp”与”alphabet”不一样,因为它不包括”habet”。
与Perl不同,不需要将正则表达式封装在//中。
如果没有末尾”/”该如何使用修饰符i、s、m、x呢?解决方案是使用扩展正则表达式,即/abc/i变形为(?i)abc。参见 修饰词的放置。
例子
正则表达式提取器说明:
面板选项或字段 | 含义 |
---|---|
Apply to | 应用范围 |
要检查的响应字段 | 样本数据源 |
引用名称 | 其他地方引用时的变量名称,引用方法:${引用名称} |
正则表达式 | 数据提取器 |
模板 | 对应正则表达式提取器类型,样式为:1。若为:0,则为所有的匹配数据 |
匹配数字 | 正则表达式匹配数据的最终结果可以看做一个数组,匹配数字即可看做是数组的第几个元素。当为 0 时,随机返回匹配的数据,当为 1 时,表示返回匹配结果数组的第一个元素 |
缺省值 | 匹配失败时的默认值。通常用于后续的逻辑判断,一般通常为特定含义的英文大写单词组合,简单可写为 ERROR。 |
提取单个字符串
假设想要从web页面的以下部分进行匹配:
name=”file” value=”readme.txt”>
从中提取”readme.txt”
一个适当的表达式是:
name=”file” value=”(.+?)”>
上面特殊的字符是:
(和):闭合的括号将匹配的部分当成一个整体返回
. :匹配任何字符
+ :匹配一次或者多次(至少一次)
? :非贪婪的,匹配到一个就终止匹配(即匹配0次或者1次)
注意:如果没有 ? ,.+将会跳过第一个>直到最后一个>,这可能不是我们想要的
注意:尽管上面的表达式取到了我们想要的结果,使用下面的表达式更有效率
name=”file” value=”([^”]+)”>
[^”] 意味着除了不匹配”之外,匹配任何组合
在这种情况下,匹配引擎在匹配到第一个”就停止搜索
在这种情况下,匹配引擎可以在找到第一个”就停止查找,而在前面的例子中,引擎必须检查它找到的是 ”>而不是” >
匹配数字:是指匹配第几个
默认值:当匹配不到的时候用默认值
抽取多个字符串
假设想要从web页面的以下部分进行匹配:
name=”file.name” value=”readme.txt”
同时提取file.name和readme.txt。
一个合适的正则表达式是:
name=”([^”]+)” value=”([^”]+)”
这将创建两个组,可以在JMeter正则表达式提取器模板中使用$1$和$2$。
JMeter Regex提取器在其他变量中保存组的值。
例如,假设:
引用名:RefName
正则表达式:name=”(.+?)” value=”(. + ?)”
模板:$1$$2$
不将正则表达式包含在/ /
以下的变量将被设置:
RefName:file.namereadme.txt
RefName_g:groups的数量(在此为2)
RefName_g0:name=”file.name” value=”readme.txt”
RefName_g1:file.name
RefName_g2: readme.txt
这些变量可以在JMeter测试计划中稍后引用,如
${RefName},${RefName_g0}、${RefName_g1}、${RefName_g2}。
还是以百度搜索控件为例我们取出id和name结果存储在引用(也可以叫变量,我习惯称之为变量)name中(这个名字只要合法就行,下面的例子中要引用这个名字~)
引用名称:name
正则表达式:<input id=(.*) name=(.*) class=s_ipt value maxlength=255 模版:$1$ $2$
注意:模版中我使用的$1$\ $2\$有个个空格,所以结果为kw wd
下面分别演示在断言中引用存储的变量
使用name_g0:值为<input id=kw name=wd class=s_ipt value maxlength=255,断言成功
使用name_g1:值为kw,断言成功
使用name_g2:值为wd,断言成功
使用name:值为kw wd,所有断言失败
可以使用debug postprocessor可以查看(后续会详细介绍调试)
行模式
模式匹配的行为方式略有不同,这取决于多行和单行修饰符的设置。注意,单行和多行操作符之间没有任何关系;它们可以独立地指定。
单行模式
单行模式只会影响元字符”.”的解释方式。默认情况下”.”匹配任何字符,除了换行符。
在单行的模式中”.”也能匹配换行符。
多行模式
多行模式只会影响元字符^和$被解释的方式。默认行为是^和$仅在字符串的开头和结尾匹配。当使用多行模式时,元字符^在每一行的开头都匹配,元字符$在每一行末尾匹配。
元字符
正则表达式使用某些字符作为元字符-这些字符对RE引擎有特殊的意义。这样的字符若想当做普通的字符来使用必须通过(反斜线)来转义,元字符的列表和它们的含义(如果有疑问请检查一下ORO文档)。
符号 | 含义 |
---|---|
( and ) | 分组 |
[ and ] | 字符集合意味着匹配一组字符中的一个 |
{ and } | 重复的字符,字符对{}指定所匹配字符的出现次数。de{1,3}f匹配def,deef和deeef;de{3}f匹配deeef;de{3,}f匹配不少于3个e在d和f之间;de{0,3}f匹配不多于3个e在d和f之间 |
*,+ and ? | 重复的字符,前两个是贪婪的,?是非贪婪的 |
. | 单个字符的通配符 |
\ | 转义字符 |
| | 或者 |
^ and $ | 字符串或者行的开始和结尾 |
下面的Perl5扩展正则表达式是由ORO支持的
表达式 | 含义 |
---|---|
(?#text) | 模式注释,嵌入的注释将被忽略 |
(?:regexp) | 不存贮括号内的匹配内容 ,在PERL的模式中,括号内的子模式将存贮在内存中,此功能即取消存贮该括号内的匹配内容,如/(?:a|b|c)(d|e)f \1/中的\1表示已匹配的d或e,而不是a或b或c |
(?=regexp) | 一个零宽度的肯定的预见断言。其意义为匹配后面为string的模式,例如,\w+(?=\s)匹配一个单词后面跟着空格,但匹配结果中不包含空格。再比如:string = “25abc8”; string =~ /abc(?=[0-9])/; matched = $&; # $&为已匹配的模式,此处为abc,而不是abc8 |
(?!regexp) | 一个0宽度的否定的预见匹配,意义为匹配后面非string的模式,例如 foo(?!bar) 匹配任何foo*但是不能匹配后面跟bar的字符串。记住这个一个0宽度的断言a(?!b)d将匹配ad,因为a后面跟随的是字符d(不是b)并且a d遵循零宽度断言。 |
(?imsx) | 通常模式选项置于其后,有四个选项:i、m、s、x可以内嵌使用,语法为:/(?option)pattern/,等价于/pattern/option |
修饰符位置
修饰符可以放在regex的任何地方,并从该点开始应用。【在ORO的一个bug指出不能在正则表达式的末尾使用它们。无论如何,他们都没有效果】。
单行(?s)和多行(?m)修饰符通常放在正则表达式的开头。
忽略大小写的修饰符(?i)可以有效地应用于正则表达式的一部分,例如:
Match ExAct case or (?i)ArBiTrARY(?-i) case
将会匹配 Match ExAct case or arbitrary ,也会匹配 Match ExAct case or ARBitrary ,但不会匹配 Match exact case or ArBiTrARY 。
测试正则表达式
自JMeter 2.4以来,”View Results Tree”包括一个RegExp测试器,用于在采样响应数据上直接测试正则表达式。
有一个网站可以测试Java正则表达式。
另一种方法是使用一个简单的测试计划来测试正则表达式。可以使用Java请求采样器生成一个示例,或者使用HTTP采样器来加载一个文件。添加一个调试采样器和一个树视图侦听器,并且对正则表达式的更改可以快速地进行测试,而不需要访问任何外部服务器。
在观察结果树种编辑正则表达式,勾选regular exp ,点击搜索,在观察结果树中若有匹配则将结果树中的label自动用红颜色的框框起来(每个请求的小框~大框我画的)。