スクリプトガイド > データタイプ > パターンマッチ
公開日: 04/01/2021

パターンマッチ

JSLのパターンマッチを使うと、文字列を柔軟に検索・処理することができます。

パターン変数は、JMPの他の変数と同様に定義・使用します。

i = 3; // 数値変数
a = "Ralph"; // 文字変数
t = textbox("Madge"); // ディスプレイボックス変数
p = ( "this" | "that" ) + patSpan(" ")
		+ ( "car" | "bus" ); // パターン変数

上のステートメントを実行すると、pにパターン値が割り当てられます。パターン値は、他のパターンを作成したり、パターンマッチを実行したりするのに使用できます。patSpan関数は、引数で指定された文字列にマッチするパターンを戻します。たとえば、patSpan("0123456789")は0から9までの数字とマッチします。

p2 = "Take " + p + "."; // pを使って他のパターンを作成する
If( Pat Match( "Take this bus.", p2 ), // マッチの実行
	Print( "matches" ),
	Print( "no match" )
);

上記のように、パターンがソーステキストとマッチすることだけを知りたい場合もあれば、マッチしたのがバスか車かなど、何がマッチしたのかを知りたい場合もあります。

p = ("this" | "that") + Pat Span( " " ) + ("car" | "bus") >?
vehicleType; // パターンがマッチした場合のみ、変数に値を割り当てる
If( Pat Match( "Take this bus.", p ),

// ELSEではvehicleTypeが設定されていないので使用しない

	Show( vehicleType ),
	Print( "no match" )
);

上のプログラムでは、ifにおいてパターンマッチの結果をチェックする必要がないので、変数(vehicleType)にデフォルト値をあらかじめ代入しておけばよいでしょう。条件割り当て演算子>?には2つのオペランドがあります。最初のオペランド(左辺)がパターンで、2番目(右辺)が変数名です。>?は、第1引数でパターンを作成し、全体のパターンマッチが成功したら、第1引数とのマッチングの結果を変数(第2引数)に保存します。>>も同様に変数に結果を保存しますが、全体のパターンマッチの成功を待ちません。>>に指定されたパターンがマッチするとそのたびに即座に割り当てが実行されます。

findDelimString = Pat Len( 3 ) >> beginDelim + Pat Arb() >? middlePart
+Expr( beginDelim );
testString = "SomeoneSawTheQuickBrownFoxJumpOverTheLazyDog'sBack";
rc = Pat Match( testString, findDelimString, "<<<" || middlePart || ">>>" );
Show( rc, beginDelim, middlePart, testString );

上の例では、patMatch関数の3番目の引数として置き換え文字列が使用されています。ここでは、3つの文字列を連結(||演算子)したものに置換されます。3つの文字列のうち、middlePartは、testStringから>?によって抽出されたものです。置き換えはパターンマッチが成功(rc == 1)しなければ実行されないため、このような指定は適切です。

findDelimStringに割り当てられたパターンを見てみましょう。3つのパターンの連結です。最初のPatLen(3)で任意の3文字とマッチさせ、その結果が>>演算子によりbeginDelimに割り当てられます。2番目は>?で任意の文字数の文字列とマッチさせ、>?演算子によりすべてのマッチングが成功した場合、結果をmiddlePartに割り当てます。最後は式で、パターンが作成されたときではなく、パターンが実行されたときにbeginDelimに保持された文字列で構成されます。expr()と同様、引数の評価は実行時に行われます。それにより、パターンは、文中の2箇所に現れる同一の3文字の文字列を検索します。

適切なパターン関数を使うことにより、処理が速くなったり、プログラミングが簡単になったりする場合があります。たとえば、"a"|"b"|"c"patAny("abc")と等価です。patNotAny("abc")は"abc"を含まない文字列とマッチします。patBreak("0123456789")は、最初に出会った数字までの文字列(その数字は含まない)とマッチします。このようなパターンは、patNotAnyPatBreak関数を使用せずに記述するのは大変です。

次の例は、小数、指数、記号から構成される数値の文字列とマッチするパターンです。このパターンは、数字のない特殊なケースのマッチも行います。数字に割り当てられたパターンに特に注目してください。

digits = Pat Span( "0123456789" ) | "";
 
number = (Pat Any( "+-" ) | "") >? signPart + (digits) >? wholePart + ("."
+digits | "") >? fractionPart + (Pat Any( "eEdD" ) + (Pat Any( "+-" ) | "")
 + digits | "") >? exponentPart;
 
If( Pat Match( "-123.456e-78", number ),
	Show( signPart, wholePart, fractionPart, exponentPart )
);
より詳細な情報が必要な場合や、質問があるときは、JMPユーザーコミュニティで答えを見つけましょう (community.jmp.com).