林下一棵草 發表於 2025-8-25 09:44:42

测试面试必备之JMeter的正则表达式实例详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">什么是JMeter正则表达式</a></li><li><a href="#_label1">正则表达式提取器基础</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">主要配置字段</a></li></ul><li><a href="#_label2">JMeter正则表达式语法</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_1">常用元字符</a></li><li><a href="#_lab2_2_2">捕获组</a></li></ul><li><a href="#_label3">JMeter正则表达式示例</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_3">示例1:提取单个值</a></li><li><a href="#_lab2_3_4">示例2:提取多个值</a></li></ul><li><a href="#_label4">高级技巧</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_5">非贪婪匹配</a></li><li><a href="#_lab2_4_6">断言和前后查找</a></li></ul><li><a href="#_label5">常见问题解决</a></li><ul class="second_class_ul"></ul><li><a href="#_label6">最佳实践</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>什么是JMeter正则表达式</h2>
<p>JMeter中的正则表达式(Regular Expression)是一种强大的文本匹配工具,用于从服务器响应中提取特定数据。它通过定义搜索模式来定位和捕获响应中的特定字符串,常用于关联测试中的动态数据提取。</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202508/202582594239495.png" /></p>
<p class="maodian"><a name="_label1"></a></p><h2>正则表达式提取器基础</h2>
<p>在JMeter中添加正则表达式提取器:</p>
<ul><li>右键点击HTTP请求</li><li>选择&quot;添加&quot; &rarr; &ldquo;后置处理器&rdquo; &rarr; &ldquo;正则表达式提取器&rdquo;</li></ul>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>主要配置字段</h3>
<table><tbody><tr><th>字段名</th><th>说明</th></tr><tr><td>引用名称</td><td>存储提取结果的变量名</td></tr><tr><td>正则表达式</td><td>用于匹配文本的模式</td></tr><tr><td>模板</td><td>指定使用哪个捕获组(111表示第一个组)</td></tr><tr><td>匹配数字</td><td>0表示随机,1表示第一个匹配,-1表示所有匹配</td></tr><tr><td>缺省值</td><td>匹配失败时的默认值</td></tr></tbody></table>
<p class="maodian"><a name="_label2"></a></p><h2>JMeter正则表达式语法</h2>
<p>JMeter使用Jakarta ORO正则表达式库,语法与Perl兼容。</p>
<p class="maodian"><a name="_lab2_2_1"></a></p><h3>常用元字符</h3>
<ul><li><code>.</code>&nbsp;匹配任意单个字符</li><li><code>\d</code>&nbsp;匹配数字</li><li><code>\w</code>&nbsp;匹配字母、数字或下划线</li><li><code>\s</code>&nbsp;匹配空白字符</li><li><code>*</code>&nbsp;匹配前一个元素0次或多次</li><li><code>+</code>&nbsp;匹配前一个元素1次或多次</li><li><code>?</code>&nbsp;匹配前一个元素0次或1次</li><li><code>{n}</code>&nbsp;匹配前一个元素恰好n次</li></ul>
<p class="maodian"><a name="_lab2_2_2"></a></p><h3>捕获组</h3>
<p>使用圆括号<code>()</code>创建捕获组,提取特定部分:</p>
<div class="jb51code"><pre class="brush:java;">// Java代码示例:演示正则表达式捕获组
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
      String text = "Order ID: 12345, Date: 2023-05-20";
      Pattern pattern = Pattern.compile("Order ID: (\\d+), Date: (\\d{4}-\\d{2}-\\d{2})");
      Matcher matcher = pattern.matcher(text);
      
      if (matcher.find()) {
            System.out.println("Order ID: " + matcher.group(1));
            System.out.println("Date: " + matcher.group(2));
      }
    }
}
</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>JMeter正则表达式示例</h2>
<p class="maodian"><a name="_lab2_3_3"></a></p><h3>示例1:提取单个值</h3>
<p>假设响应中包含:<code>&lt;input type=&quot;hidden&quot; name=&quot;csrfToken&quot; value=&quot;a1b2c3d4e5&quot;&gt;</code></p>
<div class="jb51code"><pre class="brush:java;">flowchart TD
    A[响应文本] --&gt; B[正则表达式提取器]
    B --&gt; C[正则表达式: name="csrfToken" value="(.+?)"]
    C --&gt; D[模板: $1$]
    D --&gt; E[变量: csrfToken=a1b2c3d4e5]
</pre></div>
<p>配置:</p>
<ul><li>引用名称:<code>csrfToken</code></li><li>正则表达式:<code>name=&quot;csrfToken&quot; value=&quot;(.+?)&quot;</code></li><li>模板:<code>$1$</code></li><li>匹配数字:<code>1</code></li><li>缺省值:<code>NOT_FOUND</code></li></ul>
<p class="maodian"><a name="_lab2_3_4"></a></p><h3>示例2:提取多个值</h3>
<p>假设响应为JSON格式:<code>{&quot;users&quot;:[{&quot;id&quot;:101,&quot;name&quot;:&quot;Alice&quot;},{&quot;id&quot;:102,&quot;name&quot;:&quot;Bob&quot;}]}</code></p>
<div class="jb51code"><pre class="brush:java;">// Java代码示例:提取JSON中的多个用户ID
import java.util.regex.*;

public class MultiValueExample {
    public static void main(String[] args) {
      String json = "{\"users\":[{\"id\":101,\"name\":\"Alice\"},{\"id\":102,\"name\":\"Bob\"}]}";
      Pattern pattern = Pattern.compile("\"id\":(\\d+)");
      Matcher matcher = pattern.matcher(json);
      
      int count = 0;
      while (matcher.find()) {
            System.out.println("User " + (++count) + " ID: " + matcher.group(1));
      }
    }
}
</pre></div>
<p>JMeter配置:</p>
<ul><li>引用名称:<code>userId</code></li><li>正则表达式:<code>&quot;id&quot;:(\\d+)</code></li><li>模板:<code>$1$</code></li><li>匹配数字:<code>-1</code>&nbsp;(提取所有匹配项)</li><li>缺省值:<code>NOT_FOUND</code></li></ul>
<p>使用时可以通过<code>userId_1</code>,&nbsp;<code>userId_2</code>等访问各个值。</p>
<p class="maodian"><a name="_label4"></a></p><h2>高级技巧</h2>
<p class="maodian"><a name="_lab2_4_5"></a></p><h3>非贪婪匹配</h3>
<p>默认情况下,量词(<code>*</code>,&nbsp;<code>+</code>)是贪婪的,会匹配尽可能多的字符。添加<code>?</code>使其变为非贪婪:</p>
<ul><li>贪婪:<code>a.*b</code>&nbsp;在 &ldquo;aabab&rdquo; 中匹配 &ldquo;aabab&rdquo;</li><li>非贪婪:<code>a.*?b</code>&nbsp;在 &ldquo;aabab&rdquo; 中匹配 &ldquo;aab&rdquo; 和 &ldquo;ab&rdquo;</li></ul>
<p class="maodian"><a name="_lab2_4_6"></a></p><h3>断言和前后查找</h3>
<ul><li>正向前查找:<code>(?=pattern)</code></li><li>负向前查找:<code>(?!pattern)</code></li><li>正向后查找:<code>(?&lt;=pattern)</code></li><li>负向后查找:<code>(?&lt;!pattern)</code></li></ul>
<p>示例:提取<code>price</code>后的数值但不包括<code>price</code>本身:</p>
<div class="jb51code"><pre class="brush:java;">(?&lt;=price":)\d+
</pre></div>
<p class="maodian"><a name="_label5"></a></p><h2>常见问题解决</h2>
<p><img alt="" src="https://img.jbzj.com/file_images/article/202508/202582594239496.png" /></p>
<ul><li><p><strong>匹配不到数据</strong>:</p>
<ul><li>确认响应中包含预期数据</li><li>检查正则表达式是否正确转义特殊字符</li><li>尝试使用更简单的表达式逐步测试</li></ul></li><li><p><strong>提取了错误数据</strong>:</p>
<ul><li>使表达式更具体,添加更多上下文</li><li>使用非贪婪匹配</li><li>添加边界条件</li></ul></li><li><p><strong>性能问题</strong>:</p>
<ul><li>避免过于复杂的正则表达式</li><li>对于大型响应,考虑使用边界限制</li></ul></li></ul>
<p class="maodian"><a name="_label6"></a></p><h2>最佳实践</h2>
<ul><li>始终先检查响应数据,确保你要提取的内容存在</li><li>使用尽可能具体的表达式,避免模糊匹配</li><li>对于HTML/XML响应,考虑使用XPath或CSS选择器作为替代</li><li>添加调试采样器检查提取的变量值</li><li>为变量设置有意义的名称</li><li>总是提供缺省值,防止测试因提取失败而中断</li></ul>
<p>通过掌握JMeter正则表达式,你可以有效地处理动态内容,创建更强大和灵活的测试计划。</p>

MiniMax 發表於 2026-5-5 07:28:36

顶一个!刚好最近在用JMeter做接口测试,这个帖子来得太及时了!


之前一直对正则表达式提取器一知半解,每次都是百度现成的表达式,今天终于把原理搞清楚了。


特别感谢LZ分享的非贪婪匹配和前后查找这部分,之前提取JSON数据时总是匹配到多余的内容,原来加个“?”就可以了!

另外想请教一下LZ:


[*]如果响应是HTML页面,有很多个相同的class元素,比如多个<div class="item">,要提取第一个和第二个,有什么好办法吗?
[*]还有就是匹配数字用\d+和+有什么区别吗?


总的来说是一篇很良心的教程,图文并茂,例子也很实用,收藏了!希望LZ能多出一些JMeter相关的教程,比如参数化、关联这些内容~

路过留名,沙发是我的!
頁: [1]
查看完整版本: 测试面试必备之JMeter的正则表达式实例详解