正则表达式(Regular Expressions)
1、概述(Overview)
JMeter包含模式匹配软件Apache Jakarta ORO。
在Jakarta网站上有一些相关的文档,例如模式匹配字符的摘要。
在OROMatcher用户指南中也有关于旧版本的文档,可能会很有用。
模式匹配非常类似于Perl( perl 是一门程序语言)中的模式匹配。完整的Perl安装将包含大量关于正则表达式的文档—查找perlrequick、perlretut、perlre和perlreref。
值得强调的是“包含”和“匹配”之间的区别,就像在响应断言测试元素中使用的那样:
“包含”
表示正则表达式至少匹配目标的某些部分,所以单词“ alphabet”包含“ph.b”,因为正则表达式匹配子字符串“phabe”。
“匹配”
表示正则表达式匹配整个目标。所以“alphabet”和“al.*t”是匹配的。
在这种情况下,它相当于包装^和$的正则表达式,即“^al.*t$”。
然而,情况并非总是如此。例如,正则表达式“alp|.lp”。“”是“包含”在“ alphabet”中,但不“匹配”在“字母表”中。
为什么?因为当模式匹配器在“alphabet”中发现序列“alp”时,它停止尝试任何其他组合——“alp”与“alphabet”并不相同,因为它不包括“habet”。
与Perl不同,没有必要(即不)将正则表达式括在 // 中。
如果没有尾随/,如何使用修饰符ismx等?解决方案是使用扩展正则表达式,例如/abc/i变成(?i)abc。请参见下面修饰符的位置(第5节)。
2、示例
提取单个字符串
假设您希望匹配web页面的以下部分:
name = "file" value = "readme.txt">
你想要提取readme.txt。
适当的正则表达式是:
name = "file" value = "(+ ?)">
上述字符解释如下:
( ) 这些包含要返回的匹配字符串的部分
. 匹配任何字符
+ 一次或多次
? 匹配到第一个就停止,不再继续匹配
注意:如果没有?,.+将继续超过第一个 ">,如果不止一个** ">**,直到找到最后一个可能的 "> 。
注意:虽然上面的表达式是有效的,但是使用下面的表达式会更有效:
name = "file" value = "([^ "]+)">
[^"] ——意味着匹配除了"
在这种情况下,匹配引擎可以在看到第一个"时立即停止查找,而在以前的情况下,引擎必须检查它是否找到了">而不是" >。
注意">和" >的区别。
提取多个字符串
假设您希望匹配web页面的以下部分:
name = " file.name " value = "readme"。您想要同时提取两个file.name 和 readme.txt。
适当的正则表达式是:
name="([^"]+)" value="([^"]+)"
这将创建两个组,可以在JMeter正则表达式提取器模板中使用,分别为 $1$ 和 $2$。
JMeter Regex提取器在其他变量中保存组的值。
例如,假设:
- 引用名称:MYREF
- Regex:name = "(. + ?)" value = "(. + ?)"
- 模板:$ 1 $ $ 2 $
不要在/ /中包含正则表达式
将设置以下变量:
MYREF
file.namereadme.txt
MYREF_g0
name="file.name" value="readme.txt"
MYREF_g1
file.name
MYREF_g2
readme.txt
这些变量可以在JMeter测试计划的后面提到,如${MYREF}, ${MYREF_g1}等等。
3、行模式(Line mode)
根据多行和单行修饰符的设置,模式匹配以各种略有不同的方式进行。注意,单线和多线操作符之间没有任何关系;它们可以单独指定。
单行模式(Single-line mode
)
单行模式只影响 . 元字符解释。
默认行为就是这样 . 匹配除换行之外的任何字符。在单行的模式中, .也匹配换行符。
多行模式(Multi-line mode
)
多行模式只会影响元字符^和$解释。
默认行为是^和$只匹配字符串的开始和结束。当使用多行模式,^元字符匹配的每一行的开始,和$元字符匹配的每一行的末尾。
4、元字符(Meta characters)
正则表达式使用某些字符作为元字符——这些字符对RE引擎有特殊的意义。这样的字符必须在前面加上斜杠,以便将它们视为普通字符。以下是元字符的列表及其含义(如果有疑问,请查看ORO文档)。
()
分组
[]
字符类
{}
重复
*、+和?
重复
.
通配符字符
\
转义字符
|
选择
^和$
字符串或行(line)的开始和结束
请注意,ORO不支持\Q和\E元字符。在其他的RE引擎中,它们可以用来引用RE的一部分,以便元字符代表它们自己。您可以使用函数来执行相同的操作,请参见${__escapeOroregon expchars(valueToEscape)}。
下面的Perl5扩展正则表达式由ORO支持。
(? #text)
导致文本被忽略的嵌入注释。
(?:regexp)
分组诸如“()”之类的东西,但不会导致保存组匹配。
(? = regexp)
一个零宽度的正向前视断言。例如,\w+(?=\s)匹配后跟空格的单词,而不包括匹配结果中的空格。
(? ! regexp)
一个零宽度的否定前视断言。例如,foo(?!bar)匹配任何不跟在bar后面的“foo”的出现。记住,这是一个零宽度断言,这意味着a(?!b)d将匹配ad,因为a后面跟着的字符不是b (d),而d后面跟着零宽度断言。
(? imsx)
一个或多个嵌入的模式匹配修饰符。我支持用例不敏感,m支持对输入的多行处理,s支持对输入的单行处理,并且x支持扩展的空白注释。
注意(?<=regexp) - lookbehind -不受支持。
5、修饰词的位置(Placement of modifiers)
修饰符可以放在regex中的任何位置,并从该点开始应用。ORO中的一个bug意味着它们不能在regex的最后使用。然而,无论如何,它们都不会有任何影响。
单行(?s)和多行(?m)修饰符通常放在regex的开头。
忽略大小写修饰符(?i)可能只用于正则表达式的一部分,例如:
Match ExAct case or (?i)ArBiTrARY(?-i) case
将匹配 Match ExAct case or arbitrary case 和 Match ExAct case or ARBitrary case, 但是不匹配 Match exact case or ArBiTrARY case.
6、测试正则表达式
由于JMeter 2.4,监听器查看结果树包含一个RegExp测试器,可以直接在采样器响应数据上测试正则表达式。
有一个网站可以测试Java正则表达式。
另一种方法是使用一个简单的测试计划来测试正则表达式。可以使用Java请求采样器生成示例,也可以使用HTTP采样器加载文件。添加一个调试采样器和一个树视图监听器,可以快速测试对正则表达式的更改,而不需要访问任何外部服务器。
本文原文。