# JMeter官方文档：21. 正则表达式



[《JMeter官方文档--翻译计划》](/2017/08/24/jmeter-translation-plans/) [原文地址](http://jmeter.apache.org/usermanual/regular_expressions.html)

## 21. 正则表达式
---
### 21.1 概述
---
JMeter 包含模式匹配软件 [Apache Jakarta ORO](http://attic.apache.org/projects/jakarta-oro.html) 。  
在 Jakarta 网上有一些关于它的文档，例如：[模式匹配字符摘要](http://archimedes.fas.harvard.edu/scrapbook/jakarta-oro-2.0.6/docs/api/org/apache/oro/text/regex/package-summary.html)。  

在 [OROMatcher 用户指南](http://www.savarese.org/oro/docs/OROMatcher/index.html)上还有一个关于该产品旧版本的文档 ，也许会有些用处。  

模式匹配与 Perl 中的模式匹配非常类似。Perl 的完整安装会包含大量关于正则表达式的文档——查找 __perlrequick__， __perlretut__， __perlre__ 和 __perlreref__。  

有必要强调“包含（contains）”和“匹配（matches）”之间的区别，它们被用在响应断言测试原件上：

"_包含（contains）_" 意味着正则表达式至少与目标的某个部分相匹配，所以 '__alphabet__' “包含” '__ph.b.__'，因为正则表达式匹配子字符串 '__phabe__'。  

"_匹配（matches）_" 意味着正则表达式匹配整个目标。所以 '__alphabet__' 和 '__al.*t__' 是“匹配”的 。  
这种情况下，它相当于将正则表达式封装在 __^__ 和 __$__ 中，即 '__^al.*t$__'。  

然而，情况并非总是如此。例如，正则表达式 '__alp|.lp.*__' “包含”于 '__alphabet__'，但并不“匹配” '__alphabet__'。  

这是为什么？原因是当模式匹配器在 '__alphabet__' 中找到序列 '__alp__' 时，它将停止尝试其他组合——而 '__alp__' 与 '__alphabet__' 不同，它不包含 '__habet__'。

>不同于 Perl，没有必要将正则表达式用 // 封装。

那么如果没有尾部的 __/__，该如何使用 __ismx__ 等修饰符呢？解决方法是使用扩展的正则表达式，即 __/abc/i__ 变成 __(?i)abc__。请参阅下面的[21.5 修饰符的放置](#215-修饰符的放置)。

### 21.2 举例
---
##### 提取单个字符串
---
假设您想要匹配网页的以下部分：   
__name="file" value="readme.txt">__   
并且要提取 __readme.txt__。

一个符合的正则表达式：   
__name="file "value ="(.+?)">__

上面的特殊字符是：  
__(__ 和 __)__  　　这些包围匹配字符串的部分将被返回  

__.__  　　匹配任何字符

__+__  　　一次或多次

__？__  　　不要贪婪，即在第一次匹配成功时停止

注意：如果没有 __？__，__.+__ 找到第一个 __">__ 后会继续寻找，直到找到最后一个 __">__ ——这可能不是我们所期望的。

注意：虽然上面的正则表达式可用，但使用下面的表达式会更有效率：  
__name ="file" value ="([^"]+)">__   
其中 __[^"]__ ——表示匹配任意（除了 __"__ ），在这种情况下，匹配引擎只要找到第一个 __"__ 就可以停止查找，而在之前的情况下，引擎必须检查它是否已经找到 __">__ 而不是 __" >__。

##### 提取多个字符串
---
假设你想匹配一个网页的以下部分：  
__name ="file.name" value ="readme.txt"__，你想提取 __file.name__ 和 __readme.txt__。  
符合的正则表达式：  
__name="([^"]+)" value="([^"]+)"__  
这将创建 2 个匹配组，可以在 JMeter 正则表达式提取器模板中用 __$1$__ 和 __$2$__ 来引用。

JMeter 正则表达式提取器将组的值保存在指定变量中。

例如，假设：

* 参考名称（Reference Name）：__MYREF__
* 正则表达式（Regex）：__name="(.+?)" value="(.+?)"__
* 模板（Template）：__$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}__ 等。

### 21.3 行模式
---
模式匹配可以有不同的表现方式，这取决于多行和单行修饰符的设置。注意单行和多行操作符之间没有任何关系，它们可以单独指定。

##### 单行模式
---
单行模式只影响关键字 '__.__' 的解释。

默认情况下， '__.__' 匹配除换行符之外的任何字符。在单行模式下, '__.__' 也匹配换行符。

##### 多行模式
---
多行模式只影响关键字 '__^__' 和 '__$__' 的解释。

默认情况下 '__^__' 和 '__$__' 只匹配字符串的开头和结尾。在多行模式下，关键字 '__^__' 匹配每一行的开头，关键字 '__$__' 匹配每一行的结尾。

### 21.4 关键字
---
正则表达式使用特定字符作为关键字——这些字符对 RE 引擎有特殊的意义。这些字符必须用 __\__（反斜杠）前缀来转义，转义之后才能将它们视为普通字符。以下是关键字及其含义的列表（如有疑问，请查阅 ORO 文档）。

__(__ 和 __）__
* 分组

__[__ 和 __]__
* 字符集合

__{__ 和 __}__
* 重复

__*__，__+__ 和 __？__
* 重复

__.__
* 通配符

__\__
* 转义字符

__|__
* 选择符

__^__ 和 __$__
* 字符串或行的开始和结束

> 请注意，ORO 不支持关键字 \Q 和 \E。[在其他的 RE 引擎中，这些可以用来引用 RE 的一部分，使关键字代表它们自己。]可以使用函数来执行相同的操作，请参阅 ${__escapeOroRegexpChars(valueToEscape)}。

ORO 支持以下 Perl5 扩展正则表达式。

__(?#text)__
* 内嵌注释，可以使 __text__ 内容被忽略。

__(?:regexp)__
* 像"__()__"一样获取匹配，但并不保存匹配结果。

__(?=regexp)__
* 零长度正向肯定断言。例如，__\w+(?=\s)__ 匹配一个后跟空格的单词，匹配结果不包含空格。

__(?!regexp)__
* 零长度正向否定断言。例如，__foo(?!bar)__ 匹配任何 '__far__' 后面不跟 '__foo__' 的结果。请注意，这是一个零长度断言，这意味着 __a(?!b)d__ 匹配 __ad__，因为 __a__ 后面是一个非 __b__ 字符（__d__），而 __d__ 符合此断言。

__(?imsx)__
* 一个或多个嵌入模式匹配修饰符。__i__ 启用大小写不敏感，__m__ 启用多行输入处理，__s__ 启用单行输入处理，__x__ 启用扩展的空白注释。

<font color="red">请注意: __(?<=regexp)__ ——反向肯定断言——不支持。</font>

### 21.5 修饰符的放置
---
修饰符可以放在正则表达式的任何地方，然后从放置点开始作用。[ ORO 中有个 bug 使它们不能放在正则表达式的最后。不过，对其他没有影响。]

单行 __(?s)__ 和多行 __(?m)__ 修饰符通常放置在正则表达式的开头。

忽略大小写修饰符 __(?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__。


## 21.6 测试正则表达式
---
从 JMeter 2.4 开始，监听器[查看结果树](http://jmeter.apache.org/usermanual/component_reference.html#View_Results_Tree)包含一个正则表达式测试器，用于直接在采样器响应数据上测试正则表达式。

还有一个[网站](http://www.regexplanet.com/advanced/java/index.html)来测试 Java 正则表达式。

另一种方法是使用简单的测试计划来测试正则表达式。Java 请求采样器可用于生成示例，或 HTTP 采样器可用于加载文件。添加 Debug Sampler 和树视图监听器，可以无需访问任何外部服务器，快速测试出正则表达式的更改。




原始封面

![课程图片](https://images.unsplash.com/photo-1597230622949-6f49e8311f56?w=300)


