JMeterの正規表現の個人的な謎

はじめに

 Wicketを使用したアプリに対してJMeterでテストをしようとした場合、避けて通りにくいのが、JMeterの「正規表現抽出」です。
 なんとなく使っていたのですが、どうにも細部に謎があったので、調査しました。
 正規表現抽出とは何なのかと言いますと、以下の画像の機能です。

環境

謎1 JMeter正規表現は何のルールに則っているのか?

 Java正規表現のリファレンスを見ながら書くと、たまに不思議な挙動になることがありまして、不思議に思っておりました。
 ソースを見てやっと気づいたのですが、どうやらPerl5の正規表現互換だったようです。
 以下にorg.apache.jmeter.functions.RegexFunctionのimport部分の一部を引用します。

import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Util;

 org.apache.oroは、Jakarta OROに含まれるクラスのパッケージ名です。
 Jakarta OROは正規表現ライブラリなわけですが、importされているクラスを見るとPerl5互換のものを使用している様子。

謎2 テンプレートのところにお約束で書く$1$ってなんなのか

 これは正規表現がPerl5互換であることと関連しているようです。
 Perl5の正規表現には「キャプチャ」と呼ばれる機能があり、正規表現中の()で囲んだ部分を取り出す機能があります。
 Perl5でいうところの$1、$2が、JMeterでいうところの$1$、$2$のようです。
 (ちなみに、JMeterで1個も括弧がない場合、$1$は全体を指すが、Perl5でどうなのかは未確認)

正規表現に括弧を使った場合になんか挙動が変だと思っていたのですが、それはいつもお約束で「$1$」と私が書いていたからだったようです。
実験したところによると、正規表現全体を()で囲んでしまえばいつでも$1$で正規表現全体を示せるようです。
 (()を使いたい場合、「クラスタ化だけを行う正規表現」で表記するのも良さそうですが、実験はしてません)

謎3 一致番号とは何なのか

 正規表現にマッチする箇所が複数個あった場合に、何個目をひっこぬくか、ということです。
 最初にマッチした箇所が「0件目」ですね。
 空欄の場合は、何個目を引っこ抜くかについて、ランダムに決定されるようです。

 これが何なのか分かってなかった私は、毎回1個しかヒットしないように正規表現を工夫しておりました……。

 余談ですが、For-Eachを使う場合はお約束で「-1」にするようです。
 なぜ「-1」なのかは調べてません。

さいごに

 調べてすっきりしました。
 JMeter、マニアックな機能については日本語の解説が無くて、ついつい「動くからいいや」で済ましてしまいがち。