SenseTalkにおけるパターンの利用
SenseTalkのパターン言語を使用すると、SenseTalkの自然言語構文を用いたソーステキスト内で、パターン検索を行うことが可能になります。 パターン言語に関する一般的な説明は、SenseTalkのパターン言語の基本を参照してください。 パターン定義に関する詳細情報は、SenseTalkのパターン言語の要素を参照してください。
以下において、SenseTalkスクリプトにおけるパターンの利用に関する情報を確認できます。
パターンマッチング向けの演算子、コマンドおよび関数
パターンは、テキストを操作するコマンドや関数と同様に、指定されたテキストの存在や場所をより大きな文字列内で検出するすべてのSenseTalk演算子によってサポートされます。
set ssn to <3 digits then dash then 2 digits then dash then 4 digits>
put every offset of ssn in textblock into ssnList // テキストブロック内のssnパターンマッチのすべてのオカレンスのオフセット(最初の文字位置)を検出し、その位置をssnListリストに入れます
また、パターンとの使用に特化した演算子と関数も存在します。
Matches演算子
matches演算子を使用すると、変数または式があるパターンと正確に一致するかどうかを検証できます。 オペランドの1つはパターンでなければならず、もう一方のオペランドは文字列値として処理されます。 本演算子は、パターンが文字列全体と完全に一致する場合にtrueを返します。 パターンが文字列の一部のみと一致する、または全く一致しない場合は、matches演算子の結果はfalseとなります。
例:
put 83 matches <digit,digit> --> True
put <"x", 3 chars, "y"> matches "xyzzy" --> True
パターンが値全体と一致する可能性がある場合は、(使用している最短一致の量指定子が原因で)通常のパターンマッチが文字列全体を返さないとしても、matches演算子はtrueを返すことに注意が必要です。
put <"$", digits> matches "$895" --> True
put the occurrence of <"$", digits> in "$895" —> "$8"
最短一致と最長一致、および量指定子に関する情報は、SenseTalkのパターン言語の要素を参照してください。
Match関数とEvery Match関数
match関数とevery match関数を使用すると、テキスト内でパターンを検索できます。 match関数は特定のパターンの最初のオカレンスを検出し、every match関数はソース内におけるパターンのすべてのオカレンスを検出します。
match関数がパターンマッチを検出する場合は、本関数はそのパターンに応じて、様々なプロパティを含むマッチプロパティリストを返します。 基本パターンの場合は、プロパティリストには一致したテキストであるtextと、テキストが検出された範囲であるtext_rangeが組み込まれます。
every match関数は、プロパティリストのリストを返します。この場合、各プロパティリストにはmatch関数と同じ情報が組み込まれます。
例:
put the match of <3 digits> in "123456789" --> (text:"123", text_range:"1" to "3")
put every match of <3 digits> in "123456789" --> ((text:"123", text_range:"1" to "3"),(text:"456", text_range:"4" to "6"),(text:"789", text_range:"7" to "9"))
これらの関数に関する詳細情報は、パターンマッチング関数を参照してください。
Occurrence関数とEvery Occurrence関数
occurrence関数とevery occurrence関数は、定義されたパターンと一致するテキストを返します。 occurrence関数は最初に検出されたマッチを返し、every occurrence関数はソーステキスト内で検出された各マッチのリストを返します。
put the occurrence of <"(",chars,")"> in "sqrt(42)" --> "(42)"
put every occurrence of <3 digits> in "123456" --> (123,456)
これらの関数に関する詳細情報は、パターンマッチング関数を参照してください。
パターン内での変数と式の利用
パターンを定義する場合は、パターン要素で説明した各要素を使用できます。 ただし、状況に応じて、使用ごとに変化する要素をパターンに組み込む必要がある場合があります。
例として、15-Aug-2018という形式の日付と一致するシンプルな日付パターンを考察します。 以下のパターンは、このような日付を検出します。
set datePattern to <1 or 2 digits, "-", 3 letters, "-", 4 digits>
しかし、各日付を検出したいのではなく、スクリプト内の別の場所で決定される特定の月の日付のみを検出したいと仮定します。 この場合は、パターン内でその要素の代わりに変数を使用できます。 本パターンは、実行時に変数の値を使用して構成されます。
set month to "Oct"
set datePattern to <1 or 2 digits, "-", month, "-", 4 digits>
変数monthの値はパターン内で置換されるため、Octoberの日付のみが有効なパターンマッチとなります。
以下に、monthName()関数を使用して、month変数を現在の月の名称に設定する同様の例を示します。
set month to the abbreviated monthName -- 現在の月をパターンに対して使用します
set datePattern to <1 or 2 digits, "-", month, "-", 4 digits>
また、パターン内で直接式を使用して、上記の例を以下のように実行することも可能です。
set datePattern to<1 or 2 digits, "-", the abbreviated monthName, "-", 4 digits>
演算子を含む更に複雑な式は、丸括弧で囲む必要があります。 現在の月の日付を前年から検出するには、以下のようなパターンを使用できます。
set datePattern to <1 or 2 digits, "-", the abbreviated monthName, "-", (the year -1)>
埋め込みパターン
特定の文字列(「Oct」など)をパターンに挿入する変数のほかに、変数内ではパターン定義を使用できます。 本機能により、より大きなパターン定義にパターンを埋め込むことができます。 本技術は管理しやすい要素で構成できるため、複雑なパターンを構築する際に役立ちます。
例えば、米国の電話番号を検索するパターンが必要であると仮定します。 米国の電話番号は3桁のエリアコードと7桁の番号(3桁と4桁のグループに分けられる)で構成されます。 エリアコードは、ローカルエリア内では任意で使用でき、桁数のグループ分けにはいくつかの一般的な方法が存在します。
本例では、次のような電話番号とマッチするパターンを構築します。
555-1212
(800) 123-4567
(123)654-1111
888-222-0987
エリアコードを表示する様々な方法から始めて、これらを要素に分割してみましょう。
set areaCodeParen to <"(", 3 digits, ")", maybe a space>
set areaCodeDash to <3 digits, "-">
このどちらかのオプションを利用できるようにするために、orを使用してareaCodeパターンを構築します。
set areaCode to <areaCodeParen or areaCodeDash>
最後にlocalNumberパターンを定義し、すべての要素を1つにまとめます。
set localNumber to<3 digits, "-", 4 digits>
set phoneNumber to <maybe areaCode then localNumber>
本アプローチにより、以下のようなパターン全体を一度に定義する方法よりも判読しやすく、理解しやすいコードが得られます。
set phoneNumber to <maybe (("(", 3 digits, ")", maybe a space) or (3 digits, "-")), 3 digits, "-", 4 digits>