文字列がマッチしなかった場合、Regex Match()はゼロを要素とする空白のリストを戻します。マッチが成功すると、最初のリストはマッチ全体のテキストになります(後方参照0)。2番目のリストは後方参照1をマッチするテキスト、3番目のリストは後方参照2をマッチするテキスト・・・といった具合になります。
Regex Match(source, pattern, <replacement>|<MATCHCASE>, <NULL>)
Regex()とは異なり、Regex Match()には大文字と小文字の区別がありません。大文字と小文字を区別してマッチするには、MATCHCASEを含めます。大文字と小文字を区別してマッチし、置換するテキストがない場合は、NULLを指定します。
次の例では、名前と値のペアを解析します。
Regex Match(
"person=Fred id=77 friend= favorite=tea",
"(\w+)=(\S*) (\w+)=(\S*) (\w+)=(\S*) (\w+)=(\S*)"
);
{"person=Fred id=77 friend= favorite=tea", "person", "Fred", "id", "77", "friend", "", "favorite", "tea"}
\w+は、1個以上の文字をマッチします。\S*は、スペース以外の0個以上の文字をマッチします。結果のJSLリストでは、フィールド名(person、id、friend、favorite)とそれに対応する値(Fred、77、""、tea)が個別の文字列になります。
Regex Match()の第1引数が変数で、第3引数が置換後の値を指定する場合、マッチしたテキストは変数内で置き換えられます。
Regex()とRegex Match()は、どちらも与えられた文字列内でパターンをマッチしますが、戻す結果が異なります。文字列を別の文字列に変換するには、Regex()を使用します。パターンの特定部分にマッチする文字列部分を見つけるには、Regex Match()を使用します。
Regex()と比較して、Regex Match()のほうがより効率よく処理できる例を紹介します。sourceは、6つの文字列から成るリストです。目的は、6つの文字列の中から該当する部分を、データテーブルの「subject(主語)」、「verb(動詞)」、「object(目的語)」の各列に抽出することです。
図6.4 最終的なデータテーブル
source = {"the cat ate the chicken", "the dog chased the cat", "did ralph like mary", "the girl pets the dog",
"these words are strange", "the cat was chased by the dog"};
dt = New Table( "English 101", // データテーブルを作成する
New Column( "subject", character ),
New Column( "verb", character ),
New Column( "object", character )
);
// リスト内の文字列すべてで反復する
For( i = 1, i <= N Items( source ), i++,
// 各マッチの結果をmatchListに割り当てる
matchList = Regex Match(
source[i],
/* 各文字列をスキャンする。
各グループで0個以上の文字と1つの項目をマッチする */
".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)"
);
/* matchListの項目数がゼロの場合(文字列5)、テーブルに行を加えない。
マッチした文字列を個別のデータテーブルセルに入れる。*/
If( N Items( matchList ) > 0,
dt << Add Rows( 1 );
dt:subject = matchList[2]; // 最初の括弧のマッチ
dt:verb = matchList[3]; // 2番目の括弧のマッチ
dt:object = matchList[4]; // 3番目の括弧のマッチ
);
);
Regex Match()は、1回の試行で{"the cat was chased by the dog", "cat", "chased", "dog"}を戻します。答えがそれぞれ個別の文字列に入っています。似た例でRegex()を使う場合、1度に1つの答えが戻され、後方参照を使って最終的な文字列を構築する必要があります。
For( i = 1, i <= N Items( source ), i++,
s = Regex( source[i], ".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)", "\1" ); // 最初のグループの項目をマッチする
v = Regex( source[i], ".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)", "\2" ); // 2番目のグループの項目をマッチする
o = Regex( source[i], ".*?(cat|dog|ralph|girl).*?(ate|chased|like|pets).*?(chicken|cat|mary|dog)", "\3" ); // 3番目のグループの項目をマッチする
If( !Is Missing( s ) & !Is Missing( v ) & !Is Missing( o ),
dt << Add Rows( 1 );
dt:subject = s; // \1のマッチを戻す
dt:verb = v; // \2のマッチを戻す
dt:object = o; // \3のマッチを戻す
);
);
後方参照については、後方参照とキャプチャするグループを参照してください。