JMeterの正規表現の個人的な謎
はじめに
Wicketを使用したアプリに対してJMeterでテストをしようとした場合、避けて通りにくいのが、JMeterの「正規表現抽出」です。
なんとなく使っていたのですが、どうにも細部に謎があったので、調査しました。
正規表現抽出とは何なのかと言いますと、以下の画像の機能です。
環境
- JMeter 2.3.4
謎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」なのかは調べてません。
参考にしたサイト
調査にあたり、以下のサイトを参考にさせていただきました。
- 英語勉強日記(翻訳がんばろう日記) | bananan_wの日記 | スラド
- Perl5編 第32章 正規表現4(キャプチャとクラスタ化)
- JMeter : 正規表現とForEachコントローラ: 気の向くままに・・・