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")は、最初に出会った数字までの文字列(その数字は含まない)とマッチします。このようなパターンは、patNotAnyやPatBreak関数を使用せずに記述するのは大変です。
次の例は、小数、指数、記号から構成される数値の文字列とマッチするパターンです。このパターンは、数字のない特殊なケースのマッチも行います。数字に割り当てられたパターンに特に注目してください。
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 )
);