AppleScriptで文字列を扱う場合、検索と置換に関してはデリミタ(テキスト項目区切り)を使用することで高速に実行できます。
普通にスクリプトを組むと、検索と置換いうのは「全体の文字列を1文字目から1文字ずつずらして読み込んでいき、検索文字列と一致した部分を置換文字列と置き換えていく」という風になると思うのですが、これでは処理に時間がかかり過ぎてしまいます。何せ10KBの文章を検索&置換しようと思えば、1バイト文字で10,000回以上の処理が必要になってしまうわけですから。
そこで、「デリミタ (テキスト項目区切り)」の登場となります。デリミタは「ある文字列をリストに切り分けるための目印」のようなものと考えて下さい。以下に例を示します。
アップルスクリプトのテキスト項目区切りを“:”にする
“aaa:bbb:ccc”のすべてのテキスト項目
--- 結果:{"aaa","bbb","ccc"}
set AppleScript's text item delimiters to ":"
text items of Str
--- result : {"aaa","bbb","ccc"}
逆も考えられます。
アップルスクリプトのテキスト項目区切りを“**”にする
文字列としての{"aaa","bbb","ccc"}
--- 結果:“aaa**bbb*ccc”
set AppleScript's text item delimiters to "**"
{"aaa","bbb","ccc"} as string
--- result : "aaa**bbb**ccc"
この「アップルスクリプトのテキスト項目区切り(AppleScript's text item delimiters)」というちょっとながったらしい言葉が「AppleScriptで使用されるデリミタ」です。これには好きな文字列を必要なときに設定できます。つまり、デリミタ“:”の状態である文字列をリストに分解しておき、その文字列を今度はデリミタ“**”の状態で文字列に戻せば、もとの文字列に含まれていた“:”はすべて“**”に置換されるわけです。
例えばStrを目的の文字列とすると、
アップルスクリプトのテキスト項目区切りを“:”にする
StrをStrのすべてのテキスト項目にする
アップルスクリプトのテキスト項目区切りを“**”にする
Strを文字列としてのStrにする
set AppleScript's text item delimiters to ":"
set Str to text items of Str
set AppleScript's text item delimiters to "**"
set Str to Str as string
とするだけで、Strに含まれる“:”はすべて“**”に置換されます。簡単でしょ?
ここでちょっと注意しなければならないことがあります。それは、この「デリミタ」がスクリプト全体で共通して使用されるものだということです。(グローバル変数的、と表現できます)
例えばあるサブルーチンでデリミタを“---”にして文字列の処理をしている最中に、FindAndReplaceというサブルーチンをさらに呼んだとしましょう。このFindAndReplaceの中でもしデリミタを“+++”に変更したとすると、もとのルーチンに復帰してからもデリミタは“+++”のままになってしまいます。これが原因のエラーに、私(Karino)も最初泣かされました。
これを防ぐ方法としては、サブルーチンを開始するときにその時点のデリミタを変数に取り込んでおき、終了するときにもとのデリミタに戻すような操作をしてやるといいでしょう。
次のサブルーチンは検索&置換のためのもので、十分実用に耐えます。
FindAndReplace(targetStr,pre,pro)とは
CurDelimをアップルスクリプトのテキスト項目区切りにする
アップルスクリプトのテキスト項目区切りをpreにする
targetStrをtargetStrのすべてのテキスト項目にする
アップルスクリプトのテキスト項目区切りをproにする
targetStrを文字列としてのtargetStrにする
アップルスクリプトのテキスト項目区切りをCurDelimにする
targetStrを返す
以上
on FindAndReplace(targetStr, pre, pro)
set CurDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to pre
set targetStr to text items of targetStr
set AppleScript's text item delimiters to pro
set targetStr to targetStr as string
set AppleScript's text item delimiters to CurDelim
return targetStr
end FindAndReplace
また、純粋な「検索」(指定の文字列が何文字目から始まるか)ということも、この方法を用いれば簡単に得ることができます。(このサブルーチンはエラー処理をしていません)
Find(targetStr,findStr)とは
CurDelimをアップルスクリプトのテキスト項目区切りにする
アップルスクリプトのテキスト項目区切りをfindStrにする
targetStrをtargetStrのすべてのテキスト項目にする
NumListを{}にする
CurNumを0にする
findNumを(findStrの文字を数える)にする
iをtargetStrのおのおのにして
CurNumをCurNum+((文字列としてのi)の文字を数える)+1にする
NumListをNumList&CurNumにする
CurNumをCurNum+findNum−1にする
以上
アップルスクリプトのテキスト項目区切りをCurDelimにする
NumListの項目1から-2までを返す
以上
on Find(targetStr, findStr)
set CurDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to findStr
set targetStr to text items of targetStr
set NumList to {}
set CurNum to 0
set findNum to count character of findStr
repeat with i in targetStr
set CurNum to CurNum + (count character of (i as string)) + 1
set NumList to NumList & CurNum
set CurNum to CurNum + findNum - 1
end repeat
set AppleScript's text item delimiters to CurDelim
return items 1 thru -2 of NumList
end Find以上、デリミタを利用した検索&置換の方法でした。