Archive for the 'テキスト処理(text)' Category

05/19 指定文字列から、指定ペア文字で囲まれる部分を削除。前方からスキャンして削除実行

指定文字列に対して、指定ペア文字列で囲まれる部分を削除するAppleScriptです。

この手の処理では、文字列の前と後ろからサーチするような処理が多いですが、本プログラムはどちらも前方からサーチします。

プログラムのタイトルを見ただけでは何に使ったものかさっぱり分かりませんが、プログラムリストを見ると一目瞭然。CocoaのAPIの名前をAppleScriptObjCに自動置換するための試作品です(ものすごく強引で、やっつけ仕事のオンパレードなうえに、なんでもかんでも処理できるようにはなっていません)。

もうちょっとこねくり回すとなんとかなってくるものでしょうか。

スクリプト名:指定文字列から、指定ペア文字で囲まれる部分を削除。前方からスキャンして削除実行
–Cocoaのメソッド名をAppleScriptObjCフォーマットに変換するテスト

set aStr to "drawAtPoint:(CGPoint)point forWidth:(CGFloat)width withFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize lineBreakMode:(UILineBreakMode)lineBreakMode baselineAdjustment:(UIBaselineAdjustment)baselineAdjustment"

set sStr to "("
set eStr to ")"

–変数の型で2語に別れるものを徹底的に置換
set aStr to repChar(aStr, "unsigned short", "unsignedshort") of me
set aStr to repChar(aStr, "signed short", "signedshort") of me
set aStr to repChar(aStr, "signed int", "signedint") of me
set aStr to repChar(aStr, "unsigned int", "unsignedint") of me

if aStr does not end with ";" then
  set aStr to aStr & ";"
end if

set aStr to trimStrByCharPair(aStr, sStr, eStr, 0, 0) of me

set aStr to repChar(aStr, tab, "") of me
set aStr to repChar(aStr, character id 10, "") of me

set aStr to repChar(aStr, ";", " ") of me
set aStr to repChar(aStr, ":", "_") of me

set bList to parseByDelim(aStr, {"_", " "}) of me
set aRes to ""
repeat with i from 1 to ((length of bList) - 1) by 2
  set j to contents of item i of bList
  
set aRes to aRes & (j & "_")
end repeat

set bRes to "("
repeat with i from 2 to (length of bList) by 2
  set j to contents of item i of bList
  
set bRes to bRes & (j & ", ")
end repeat
set bRes to bRes & ")"

set bRes to repChar(bRes, ", )", ")") of me –ゴミ掃除

set cRes to aRes & bRes
–>"drawAtPoint_forWidth_withFont_minFontSize_actualFontSize_lineBreakMode_baselineAdjustment_(point, width, font, minFontSize, actualFontSize, lineBreakMode, baselineAdjustment)"

–指定文字列から、指定ペア文字で囲まれる部分を削除。前方からスキャンして削除実行
on trimStrByCharPair(aStr, sStr, eStr, sTrimOffset, eTrimOffset)
  repeat
    set sOffst to offset of sStr in aStr
    
set eOffst to offset of eStr in aStr
    
    
set aLen to length of aStr
    
if aLen < 2 then return ""
    
    
if sOffst = 0 or eOffst = 0 then
      exit repeat
    end if
    
    
if sOffst > 1 then
      set tmp1Str to text 1 thru (sOffst - 1 + sTrimOffset) of aStr
      
set tmp2Str to text (eOffst + 1 + eTrimOffset) thru -1 of aStr
      
set aStr to tmp1Str & tmp2Str
      
    else if sOffst = 1 then
      set aStr to text (eOffst + 1) thru -1 of aStr
      
    else if sOffst = aLen - 1 then
      set aStr to ""
      
    end if
    
  end repeat
  
  
return aStr
end trimStrByCharPair

–文字置換ルーチン
on repChar(origText, targStr, repStr)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

–与えられた文字列を、指定デリミタ文字でparseしてリストにして返す
on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

02/26 AppleScriptで正規表現(regexp)を

AppleScriptの基本文法に正規表現はありません。それでも、AppleScriptネイティブの機能で文字列加工などは普通にやっているわけですが、正規表現が使えないことに不満を感じているユーザーもいるようです。

でも、AppleScriptで正規表現が「使えない」なんて誰が決めたんでしょう? 標準命令セットに存在していないだけなのに。

(A)OSAXを追加
AppleScriptでは、命令などを追加するプラグイン機構「Scripting Additions」とか「OSAX」と呼ばれる仕組みがあります。

そもそも、標準命令自体が「Standard Additions」OSAXで提供されているほど。昔から正規表現を提供するOSAXは流通しており、使いたい人はインストールして使っているという状態。

ただし、どのユーザー環境にもインストールされているわけではないので、Scriptを配布して広く使ってもらうためには敷居が高いところです(自分専用のScriptであれば、問題はないでしょう)。

有名なところでは、仏Satimage Softwareの「Satimage OSAX」があります。

(B)正規表現を使えるアプリケーションを制御
正規表現を使えるアプリケーションをコントロールすれば、正規表現の使用は可能です。テキストエディタなど、対応しているものは多々あります。

ただ、これもすべてのユーザー環境にインストールされているわけではないので、Scriptを配布して広く使ってもらうという目的には合致していません。

(C)他の言語処理系を呼び出す
他の、正規表現の機能を持つ言語処理系をdo shell script命令で呼び出せば、使えることになります。

一見、ゲテモノっぽい印象がありますが、どのユーザー環境にもPerlの処理系は入っていたりするので、どのユーザー環境でも使えるというメリットがあります。サブルーチン化しておくと、再利用性も高くなることでしょう。

12/12 「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す

「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返すAppleScriptです。

ダイアログから縦横の表のサイズを文字で入力させるインタフェースを作成したときに、そのparse用として作成したものです。たいしたものではありません。

スクリプト名:「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す
set aStr to "3×4"
set aRes to divideYxX(aStr) of me
–> {3, 4}

–「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す
on divideYxX(aStr)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to "x"
  
set tList to every text item of aStr
  
set AppleScript’s text item delimiters to curDelim
  
  
copy tList to {item1, item2}
  
try
    set item1 to item1 as integer
    
set item2 to item2 as integer
  on error
    return false
  end try
  
  
return {item1, item2}
  
end divideYxX

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

10/10 文字列中に指定文字が何個入っているかカウントする v2

文字列中に指定文字が何個入っているかカウントし、出現数と出現位置のリストを返すAppleScriptです。

スクリプト名:文字列中に指定文字が何個入っているかカウントする v2
set a to “Joe A Hisaishi”
set aTargChar to ” “

set bList to countAcharInStrAndDetectPos(a, aTargChar) of me
–> {2, {4, 6}} –指定文字の出現回数カウント、登場位置リスト

–文字列中に指定文字が何個入っているかカウントし、登場位置をリストで返す
on countAcharInStrAndDetectPos(aStr, aTargChar)
  set aList to {}
  
set posC to 1
  
  
considering case
    set aHit to offset of aTargChar in aStr
    
    
if aHit is not equal to 0 then
      set aaList to characters of aStr
      
set aCount to 0
      
      
repeat with i in aaList
        
        
set j to contents of i
        
        
if j = aTargChar then
          set aCount to aCount + 1
          
set the end of aList to posC
        end if
        
        
set posC to posC + 1
        
      end repeat
      
      
      
return {aCount, aList}
    else
      return {0, {}}
    end if
  end considering
end countAcharInStrAndDetectPos

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/07 AppleScript中にファイルパスを記述する

いろいろ質問が寄せられていたり、US Appleのメーリングリストでも投稿数を統計的に分析(数えるだけ)すると明らかに傾向が出ています。AppleScriptに関する初心者の質問のほとんどがファイルパスに関するものです。

dd5.jpg

AppleScript上でのパスの書き方、扱い方については以下の記事を参照してください。ここでは、楽に記述する方法(作業方法)について述べます。

■AppleScriptで扱う「パス」について(1)
■AppleScriptで扱う「パス」について(2)
■AppleScriptで扱う「パス」について(3)
■AppleScriptで扱う「パス」について(4)

とくに、Mac OS Xでは(10.2あたりから?)ローカライズド・ファイルシステムが採用されているので、Finderで見ているとおり「デスクトップ」などとフォルダ名を書きたくなるところですが、実際の名前とは異なる(本当のフォルダ名は英語で「Desktop」)ためAppleScriptにエラーを返されたりと、使いやすさの実現のために実装されている機能のかずかずが仇になることもあるようです。

そこで、AppleScriptのプログラム中にファイルパスを記述する簡単な方法をご紹介しましょう。たいして難しくもなければ、悩ましいこともありません。単なる「作業」でしかありません。

やりかたは、大きくわけて2つ(私は(2)しか使いませんが、、、)。

(1)ドラッグ&ドロップ コース

Finder上でパスを調べたいファイルを選択して、AppleScriptエディタの記述エリアにそのままドラッグ&ドロップします。

dd1.jpg

すると、POSIX pathがAppleScriptエディタに入るので……

dd2.jpg

これをそのまま使用してみましょう。

スクリプト名:パスの書き方1
set a to “/Users/maro/Desktop/ScriptingBridgeFramework.pdf”
set aPath to (a as POSIX file)

–> file “Cherry:Users:maro:Desktop:ScriptingBridgeFramework.pdf”

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

こんな感じでパスを取得できます。fileのままだと受け付けないアプリケーションも多いので、「as alias」でalias(ファイル参照)にcastしてから使うとなおよいでしょう。

スクリプト名:パスの書き方1
set a to “/Users/maro/Desktop/ScriptingBridgeFramework.pdf”
set aPath to (a as POSIX file) as alias

–> alias “Cherry:Users:maro:Desktop:ScriptingBridgeFramework.pdf”

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

(2)コピー&ペースト コース

なにげにAppleScriptエディタ上に1行だけ書いて実行。ファイルのパスを求めたいときには「choose file」を、フォルダのパスを求めたい場合には「choose folder」とだけ書いて実行すればOKです。

dd3.jpg

実行してファイルを選ぶと「結果」欄にファイルのパスが表示されるので、

dd4.jpg

おもむろにパスの前後についているダブルクォートで囲まれている部分まで選択して、コピー。

別のScript(パスを書いておきたいScript)にペーストしてそのまま使用。

まあこんなもんでしょう。ただし、as aliasでファイル参照情報に変換する際に、参照先のファイルが存在しない(消したとか、名前を変更したとか)場合にはエラーになるので、try〜end tryのエラートラップを仕掛けて実行するのが大人な書き方です。

もっと「大人な」書き方をすれば、「path to」でホームディレクトリの位置を求めて、そこから相対的にどの位置にあるかといった情報を計算(文字列としてただつなぐだけ)して求めることになりますが、単に自分だけが使う「使い捨てScript」でそれほど気を使う必要もない、ということであれば……このような記述でも手っ取り早くてよいのではないでしょうか。

別のユーザー環境では動かないこと必至(HDD名称やユーザー名が違う)なので、こういうラフな書き方をしたAppleScriptは他人に配布しないように注意してください。あるいは、property文でプログラムの冒頭にまとめて書いて定義しておいて、他人の環境ではそこを直すようにコメントしておくとか。

スクリプト名:パスの書き方2
set b to “Cherry:Users:maro:Desktop:ScriptingBridgeFramework.pdf”
set bPath to b as alias

–> alias “Cherry:Users:maro:Desktop:ScriptingBridgeFramework.pdf”

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/10 文字列の先頭と末尾に指定文字が存在した場合にはトリミングして返す

与えられた文字列の先頭と末尾に指定文字が存在した場合にはトリミングして返すAppleScriptです。

指定文字列がカッコ(「(」「)」で囲まれている場合に外す、という処理を行うために用意したものです。

スクリプト名:文字列の先頭と末尾に指定文字が存在した場合にはトリミングして返す
set aStr to "(ひよこさんスペシャルサービス)"
set aRes to trimByCharPair(aStr, "(", ")") of me
–> "ひよこさんスペシャルサービス"

–文字列の先頭と末尾に指定文字が存在した場合にはトリミングして返す
on trimByCharPair(aStr, beginChar, endChar)
  
  
set aLen to length of aStr
  
set sPos to 1
  
set ePos to aLen
  
  
if aStr begins with beginChar then
    set sPos to sPos + 1
  end if
  
  
if aStr ends with endChar then
    set ePos to ePos - 1
  end if
  
  
set aResStr to text sPos thru ePos of aStr
  
return aResStr
  
end trimByCharPair

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/10 数字の文字が入っているかどうかをテストする

与えられた文字列中に数字の文字(0〜9)が入っているかテストを行うAppleScriptです。

入っていればtrueを、入っていなければfalseを返します。

スクリプト名:数字の文字が入っているかどうかをテストする
detectContainsSomeNumChar("10名") of me

–数字の文字が入っているかどうかをテストする
–数字の文字が入っていたらtrue
on detectContainsSomeNumChar(testText)
  –ANK文字列(大文字小文字は問わない)
  
set ankChar to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
  
  
set _testChar to testText as Unicode text
  
  
ignoring case
    repeat with i in _testChar
      set j to contents of i
      
if j is in ankChar then
        return true
      end if
    end repeat
  end ignoring
  
  
return false
end detectContainsSomeNumChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/10 指定アイテム以降は指定アイテム目に改行で区切って連結する

与えられたリストのうち、指定アイテム以降は指定アイテム目に改行で区切って連結するAppleScriptです。

たとえば、要素数が7つあるリストのうち、4アイテム目以降をこの処理対象と指定した場合、4〜7アイテム目が(改行をはさんて)連結されます。

スクリプト名:指定アイテム以降は指定アイテム目に改行で区切って連結する
set aList to {"○○初等部", "○○中等部", "○○高等部(400)", "○○大学", "○○女子短期大学", "○○女子短期大学"}

set a to mergeLastItem(aList, 4) of me
–>
(*
{"○○初等部", "○○中等部", "○○高等部(400)", "○○大学
○○女子短期大学
○○女子短期大学"}

*)

–指定アイテム以降は指定アイテム目に改行で区切って連結する
on mergeLastItem(aList, aLimit)
  set aLen to length of aList
  
if aLen > aLimit then
    set newItem to ""
    
    
set tmpList to items aLimit thru aLen of aList
    
set newItem to retDelimedText(tmpList, return) of me
    
    
set bList to items 1 thru (aLimit - 1) of aList
    
set the end of bList to newItem
    
set aList to bList
  end if
  
  
return aList
end mergeLastItem

on retDelimedText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimedText

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/10 文字列末尾からスペースを削る

文字列の末尾からスペース(空白文字)を削り、空白文字以外の文字に遭遇したら削除を切り上げて結果を返すAppleScriptです。

  ”PiyoPiyo ” –> “PiyoPiyo”

という処理を行います。

スクリプト名:文字列末尾からスペースを削る
set a to "GR Digital "
set b to trimSpaceFromLast(a) of me

–文字列末尾からスペースを削る
on trimSpaceFromLast(aStr)
  set revStrList to (reverse of characters of aStr)
  
set rLen to length of revStrList
  
  
set hitF to false
  
set aCount to rLen
  
  
repeat with i in revStrList
    set j to contents of i
    
    
if j is not equal to " " then
      set hitF to true
      
exit repeat
    end if
    
    
set aCount to aCount + 1
  end repeat
  
  
if hitF = false then return aStr
  
  
set bStr to text 1 thru (rLen - aCount - 1) of aStr
  
return bStr
end trimSpaceFromLast

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/10 子番号を考慮しつつ、新しいファイル名を返す

特定のフォルダ内のファイル名リストをもとに、指定のファイルを新規作成可能か(重複がないか)判断を行い、重複がある場合にはアンダースコア(「_」)のあとに子番号を補ったファイル名を生成。子番号つきのファイルがすでに存在する場合には、そのうち一番大きな番号のものを検出して、さらに新しい子番号つきのファイル名を返すAppleScriptです。

既存フォルダへのファイルのコピーなどの際に用いる、かなり高機能なルーチンです。はっきり言って上級者向けのものであり、初心者向けのものではありません。

特定のフォルダ内に、

  ”RIMG0056.JPG”, “RIMG0056_1.JPG”

というファイルが存在しており、そこに、

  ”RIMG0056.JPG”

というファイルを新規にコピーしようとした際に、ファイル名の重複を検出し、さらに子番号のうち最大のものを検出して、

  ”RIMG0056_2.JPG”

というファイル名を返します。

スクリプト名:子番号を考慮しつつ、新しいファイル名を返す

set myName to “RIMG0056.JPG”
–set aList to {”RIMG0056.JPG”, “RIMG0056_1.JPG”, “RIMG0056_2.JPG”}
set aList to {“RIMG0056.JPG”, “RIMG0056_1.JPG”}

set my2Name to retChildFileName(myName, aList) of dupNameGenKit

script dupNameGenKit
  –子番号を考慮しつつ、新しいファイル名を返す
  
on retChildFileName(myName, aList)
    
    
set numList to {}
    
–set aList to {”RIMG0056.JPG”}
    
    
repeat with i in aList
      set j to contents of i
      
      
set tmpN to offset of “_” in j
      
if tmpN is not equal to 0 then
        set tmpA to text (tmpN + 1) thru -1 of j
        
set aOfst to offset of “.” in tmpA
        
set numStr to text (tmpN + 1) thru (tmpN + aOfst - 1) of j
        
        
set the end of numList to (numStr as number)
      end if
      
    end repeat
    
    
if numList is not equal to {} then
      –すでに「_」の子番号が存在する場合
      
set b to shellSortDecending(numList) of me
      
set largestNum to contents of first item of b
      
      
set largestNum to largestNum + 1
      
    else
      –まだ「_」の子番号が存在しない場合
      
set largestNum to 1
      
    end if
    
    
set pureName to retNameFromFilenameStr(myName) of me
    
set anExt to retExtNameFromFilenameStr(myName) of me
    
set gName to pureName & “_” & (largestNum as string) & anExt
    
    
return gName
    
  end retChildFileName
  
  
  
–ファイル名文字列から拡張子を外して返す
  
on retNameFromFilenameStr(fileNameStr)
    set fLen to length of fileNameStr
    
set revText to (reverse of (characters of fileNameStr)) as string –逆順テキストを作成
    
set anOffset to offset of “.” in revText
    
set fRes to text 1 thru (fLen - anOffset) of fileNameStr
    
return fRes
  end retNameFromFilenameStr
  
  
–ファイル名文字列から拡張子のみ取得する
  
on retExtNameFromFilenameStr(fileNameStr)
    set fLen to length of fileNameStr
    
set revText to (reverse of (characters of fileNameStr)) as string –逆順テキストを作成
    
set anOffset to offset of “.” in revText
    
set fRes to text (fLen - anOffset + 1) thru -1 of fileNameStr
    
return fRes
  end retExtNameFromFilenameStr
  
  
–シェルソートでリストを昇順ソート(入れ子ではないリスト)
  
on shellSortAscending(a)
    set n to length of a
    
set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}
    
repeat with h in cols
      if (h (n - 1)) then
        repeat with i from h to (n - 1)
          set v to item (i + 1) of a
          
set j to i
          
repeat while (j h) and ((contents of item (j - h + 1) of a) > v)
            set (item (j + 1) of a) to (item (j - h + 1) of a)
            
set j to j - h
          end repeat
          
set item (j + 1) of a to v
        end repeat
      end if
    end repeat
    
return a
  end shellSortAscending
  
  
–シェルソートでリストを降順ソート(入れ子ではないリスト)
  
on shellSortDecending(a)
    set n to length of a
    
set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1}
    
repeat with h in cols
      if (h (n - 1)) then
        repeat with i from h to (n - 1)
          set v to item (i + 1) of a
          
set j to i
          
repeat while (j h) and ((contents of item (j - h + 1) of a) < v)
            set (item (j + 1) of a) to (item (j - h + 1) of a)
            
set j to j - h
          end repeat
          
set item (j + 1) of a to v
        end repeat
      end if
    end repeat
    
return a
  end shellSortDecending
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/12 コードのチェック

コードのチェックを行うAppleScriptです。

製品コードなど、決められた桁数で指定の桁が数値で一部がアルファベットになっているなど、ルールに基づいて書かれている必要のある文字列の形式チェックを行うAppleScriptです。

こういうのは、あまり書いていても面白くないですが、より汎用性を持たせたものを作ってみました。

 数値桁に「9」と書いておくと、0〜9まで受け付けます。
 数値桁に「5」と書いておくと、0〜5まで受け付けます。
 文字桁に「Z」と書いておくと、A〜Zまで受け付けます。
 文字桁に「z」と書いておくと、a〜zまで受け付けます。

スクリプト名:コードのチェック3
set aCode to "1102V01" –チェック対象のコード
set ruleCode to "9999Z99" –コードのルールを外部から供給
set aRes to chkCode(aCode, ruleCode) of me
–> {true, true, true, true, true, true, true}

set aCode to "1102-V-01" –チェック対象のコード
set ruleCode to "9999-Z-99" –コードのルールを外部から供給
set aRes to chkCode(aCode, ruleCode) of me
–> {true, true, true, true, true, true, true, true, true}

–コードのチェックを行う
on chkCode(aCode, ruleCode)
  
  
–set ruleCode to "9999Z99" –コードのルールを記述しておく–> コードのルール自体も外部から供給するようにしてみた
  
set ruleList to characters of ruleCode
  
  
–コード長のチェック
  
set rLen to length of ruleList
  
set aLen to length of aCode
  
if aLen is not equal to rLen then return false
  
  
–与えられたコードをリストに分解
  
set aList to characters of aCode
  
  
set resList to {}
  
  
repeat with i from 1 to rLen
    
    
set j1 to contents of item i of ruleList
    
set j2 to contents of item i of aList
    
    
set {fromID, toID} to getCharRange(j1) of me
    
set aCharCode to ASCII number of j2
    
    
if (aCharCode fromID) and (aCharCode toID) then
      –ルールに合っている場合には何もしない
      
set the end of resList to true
    else
      set the end of resList to false
    end if
    
  end repeat
  
  
return resList
  
end chkCode

–文字レンジを返す
on getCharRange(a)
  set aCode to ASCII number of a
  
  
if aCode 48 and aCode 57 then
    return {48, aCode} –数字(0〜指定数字まで)
  else if aCode 65 and aCode 90 then
    return {65, aCode} –アルファベット(大文字 A〜指定文字まで)
  else if aCode 97 and aCode 122 then
    return {97, aCode} –アルファベット(大文字 a〜指定文字まで)
  else
    return {aCode, aCode} –その他(ハイフンなどの記号を想定。上記とかぶらない文字)
  end if
end getCharRange

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

04/08 入れ子のリストをタブ区切りのテキストに

入れ子のリストをタブ区切りのテキストに変換するAppleScriptです。

分布リスト作成v1で作成したデータをテキスト化するために、さくっと作ってみましたが……同じものを以前に何度か作ったような……。

スクリプト名:入れ子のリストをタブ区切りのテキストに
set aList to {{"on handler1(thisYear, m)", "●", "●"}, {"on handler2(writeOutPathStr)", "●", ""}, {"on handler3(templatePath)", "●", ""}, {"on handler4(lastCellAdrNum)", "●", ""}, {"on handler5(aList, namePrefix, layerName)", "●", ""}, {"on handler2(aList, aDelim)", "", "●"}, {"on handler3(aList)", "", "●"}, {"on handler7(targetFrameName)", "", "●"}, {"on handler8(aStr)", "", "●"}}

set aText to retItemDelimedAndParagraphDelimedText(aList, tab, return) of me
–>
(*
"on handler1(thisYear, m)  ●  ●
on handler2(writeOutPathStr)  ●  
on handler3(templatePath)  ●  
on handler4(lastCellAdrNum)  ●  
on handler5(aList, namePrefix, layerName)  ●  
on handler2(aList, aDelim)    ●
on handler3(aList)    ●
on handler7(targetFrameName)    ●
on handler8(aStr)    ●
"
*)

–入れ子のリストを、アイテム間のデリミタとパラグラフ間のデリミタを指定してテキスト化
–というか、入れ子のリストをタブ区切りテキストにするのが目的
on retItemDelimedAndParagraphDelimedText(aList, itemDelim, paragraphDelim)
  set aText to ""
  
  
repeat with i in aList
    set aStr to retDelimedText(i, itemDelim) of me
    
set aText to aText & aStr & paragraphDelim
  end repeat
  
  
return aText
end retItemDelimedAndParagraphDelimedText

on retDelimedText(aList, aDelim)
  set aText to ""
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimedText

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

02/21 「m月d日」の文字列を「m/d」に変換して返す

「m月d日」のフォーマットの文字列を「m/d」に変換して返すAppleScriptです。

Mac OS X 10.6上で作成してあとから10.4.11上でも動くように対応したものです。まー、この手の簡単なテキスト整形サブルーチンは大量に生々しいものがゴロゴロしていますが、このぐらいのあたりさわりのないものしか出せないような気が、、、、

スクリプト名:「m月d日」の文字列を「m/d」に変換して返す
set aStr to "11月1日"
set aRes to retMonthSlashDateStr(aStr) of me
–> "11/1"

–「m月d日」の文字列を「m/d」に変換して返す
on retMonthSlashDateStr(aStr)
  set {mStr, dStr} to retMonthStrAndDateStr(aStr, {"月", "日"}, 2) of me
  
set resStr to mStr & "/" & dStr
  
return resStr
end retMonthSlashDateStr

–指定リストを指定デリミタでparseして日付文字列をリストにして、先頭から指定アイテムまで取り出して返す
–ただし、日付など「月」「日」が必ず存在しているという前提条件が成立するものだけが処理対象
on retMonthStrAndDateStr(aStr, delimiterList, lastItem)
  set osVer to system attribute "sys2"
  
  
if osVer 5 then
    –Mac OS X 10.5以上の場合
    
set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to delimiterList
    
set aList to text items of aStr
    
set AppleScript’s text item delimiters to curDelim
    
set bList to items 1 thru lastItem of aList
    
return bList
    
  else
    –Mac OS X 10.4以下の場合
    
set resList to {}
    
    
repeat with i in delimiterList
      set curDelim to AppleScript’s text item delimiters
      
set AppleScript’s text item delimiters to i –10.4ではデリミタをリストで指定できないので1つずつ指定
      
set aList to text items of aStr
      
set AppleScript’s text item delimiters to curDelim
      
      
set the end of resList to item 1 of aList
      
      
try
        set aStr to contents of (item 2 of aList) –ここ、あんまりよくないな〜。実害はないけど、美しくない
      end try
      
    end repeat
    
    
return resList
  end if
  
end retMonthStrAndDateStr

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/28 数字桁漢字まじり日本語的数値表現テキストをparseする

「3億4000万」とか「5那由他20京1兆301」のような桁表現に日本語固有の日本語的数値表現を行うテキストで、数字部分と漢字部分を分離してリストで返すAppleScriptです。

日本語的数値表現エンコーダー/デコーダーをAppleScriptで作っておいたのですが、桁が大きくなったときにバグが発生することが判明。そのデバッグの際に作り足したものです。

別に、日本語的数値表現を分離するだけではなく、数字とそれ以外から構成される文字列を文字種別で区切ってリストで返すといった一般的な用途にも使えます。

スクリプト名:数字桁漢字まじり日本語的数値表現テキストをparseする
set aStr to "9無量大数9997極9297載6866正6832砂1967溝1163壌4317丈7692垓2493京8466兆7286億6441万8111"
set aRes to parseNumKanji(aStr) of me
–> {"9", "無量大数", "9997", "極", "9297", "載", "6866", "正", "6832", "砂", "1967", "溝", "1163", "壌", "4317", "丈", "7692", "垓", "2493", "京", "8466", "兆", "7286", "億", "6441", "万", "8111"}

on parseNumKanji(aStr)
  set nFlag to false
  
set aList to characters of aStr
  
set nList to {}
  
  
set aFirst to contents of first item of aList
  
set aList to rest of aList
  
set nFlag to detectOutNumChar(aFirst) of me
  
  
set aStack to aFirst
  
  
repeat with i in aList
    set j to contents of i
    
set aRes to detectOutNumChar(j) of me
    
    
if not aRes = nFlag then
      set the end of nList to aStack
      
set aStack to j
      
set nFlag to not nFlag
    else
      set aStack to aStack & j
    end if
  end repeat
  
  
if aStack is not equal to "" then
    set the end of nList to aStack
  end if
  
  
return nList
end parseNumKanji

–数字範囲外の文字があるかどうかをテストする
–数字の文字以外のものが入っていたらfalse
on detectOutNumChar(testText)
  –ANK文字列(大文字小文字は問わない)
  
set ankChar to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."}
  
  
set _testChar to testText as Unicode text
  
  
ignoring case
    repeat with i in _testChar
      set j to contents of i
      
if j is not in ankChar then
        return false
      end if
    end repeat
  end ignoring
  
  
return true
end detectOutNumChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/12 ひらがなカタカナ変換

与えられた文字列のうち、ひらがなのものをカタカナに変換するAppleScriptです。

苦難のすえ、AppleScriptObjCでようやくいろいろプログラムが組めるようになってきた今日このごろ、日本語のカタカナひらがな変換APIらしきものは見つけたものの、使い方がめんどうくさそうだったので、自前で書いてしまったものです。

大量のデータ処理を行わなければ、この程度で十分でしょう。

code1.jpg

スクリプト名:ひらがなカタカナ変換
set aHiraganaStr to “漢字とひらがなでござる”

set aRes to convHiraganaToKatakana(aHiraganaStr) of me
–> “漢字トヒラガナデゴザル”

on convHiraganaToKatakana(anUnicodeText)
  set hList to characters of anUnicodeText
  
  
set newText to “”
  
repeat with i in hList
    set anID to id of i
    
if checkHiragana(anID) of me then
      set b to string id (anID + 96)
    else
      set b to i as Unicode text
    end if
    
set newText to newText & b
  end repeat
end convHiraganaToKatakana

–string idを渡すとひらがなチェックを行う
on checkHiragana(anID)
  return (anID > 12352 and anID < 12448)
end checkHiragana

–string idを渡すとカタカナチェックを行う
on checkKatakana(anID)
  return (anID > 12448 and anID < 12544)
end checkKatakana

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/30 実体参照している文字列をデコードする

HTMLの中などで実体参照(Character reference)しているエンコードされた文字列をデコードするAppleScriptです。

特定用途のために作成したので、その用途にだけ役立てばいいという割り切りをして作りました。なので、すべての用途に使えるという汎用性を保証するレベルのものではありません。

また、他の言語処理系の機能を呼び出すことで、もっと楽にできたのではないか……などとは思っています。

例によって、リスト中の半角バックスラッシュが円マーク(¥)に置き換えられていますが、AppleScriptエディタにプログラム内容を転送するリンクをクリックすれば正しい内容が転送されます。

スクリプト名:実体参照している文字列をデコードする
set aStr to "\"&#40845;&#39340;&#20253;\""
set bStr to trimStrFromTo(aStr, "\"", "\"") of me
set cRes to decodeCharacterReference(bStr) of me
–> "龍馬伝"

set aStr to "\"&#31532;2&#12456;&#12450;\"" –英数字などが混在しているパターンの文字列
set bStr to trimStrFromTo(aStr, "\"", "\"") of me
set cRes to decodeCharacterReference(bStr) of me
–> "第2エア"

–実体参照している文字列をデコードする
on decodeCharacterReference(aStr)
  set aList to parseByDelim(aStr, ";") of me
  
  
set newStr to ""
  
  
repeat with i in aList
    set j to i as string
    
if j contains "&#" then
      set aPos to offset of "&#" in j
      
set preChar to ""
      
if aPos is not equal to 1 then
        set preChar to text 1 thru (aPos - 1) of j
        
set jj to text (aPos + 2) thru -1 of j
      else
        set jj to j
        
      end if
      
      
set bStr to repChar(jj, "&#", "") of me
      
set cStr to string id (bStr as number)
    else
      set cStr to j
      
set preChar to ""
    end if
    
set newStr to newStr & preChar & cStr
  end repeat
  
  
if newStr contains "&" then
    set newStr to repChar(newStr, "&amp", "&") of me
    
set newStr to repChar(newStr, "&lt", "<") of me
    
set newStr to repChar(newStr, "&gt", ">") of me
    
set newStr to repChar(newStr, "&quot", "\"") of me
  end if
  
  
return newStr
end decodeCharacterReference

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

on trimStrFromTo(aStr, fromStr, toStr)
  –fromStrは前から探す
  
if fromStr is not equal to "" then
    set sPos to (offset of fromStr in aStr) + 1
  else
    set sPos to 1
  end if
  
  
–toStrは後ろから探す
  
if toStr is not equal to "" then
    set b to (reverse of characters of aStr) as string
    
set ePos to (offset of toStr in b)
    
set ePos to ((length of aStr) - ePos)
  else
    set ePos to length of aStr
  end if
  
set aRes to text sPos thru ePos of aStr
  
return aRes
end trimStrFromTo

–文字置換ルーチン
on repChar(origText, targStr, repStr)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/10 改行のみで囲まれた行をリストで取り出す

箇条書きのテキストの中から、改行のみの行で始まって、改行のみに行で終わるブロックをリストで取り出すAppleScriptです。

ふだん、Diary++に記入している業務日報のデータを取り出して、別のプログラムに渡せるように加工しようとしたものです。

たいした内容のプログラムではありませんが、こうして掲載しておけば何か別の機会に再利用できるかもしれません。

スクリプト名:改行のみで囲まれた行をリストで取り出す
set aStr to "職場関連:

09:30〜12:00     ひよこ手帳  資料作成
13:00〜14:30    ひよこインク  資料作成
15:00〜17:00    世界征服計画発表会  
17:00〜18:45    ひよこインク  資料作成

"
set aRes to retStartWithBlankAndEndsWithBlank(aStr) of me
–> {"", "09:30〜12:00     ひよこ手帳  資料作成", "13:00〜14:30    ひよこインク  資料作成", "15:00〜17:00    世界征服計画発表会  ", "17:00〜18:45    ひよこインク  資料作成", ""}

–改行のみで囲まれた行をリストで取り出す
on retStartWithBlankAndEndsWithBlank(aStr)
  set mList to paragraphs of aStr
  
set wList to {}
  
  
set trimF to false
  
set tStart to 0
  
set tEnd to 0
  
set tCounter to 1
  
  
repeat with i in mList
    set j to contents of i
    
set jLen to length of j
    
if trimF = false then
      if jLen = 0 then
        set tStart to tCounter
        
set trimF to true
      end if
    else
      if jLen = 0 then
        set tEnd to tCounter
        
exit repeat
      end if
    end if
    
    
set tCounter to tCounter + 1
  end repeat
  
  
set rData to items tStart thru tEnd of mList
  
return rData
  
end retStartWithBlankAndEndsWithBlank

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/31 リーダー罫文字のあとの文字を取得する

与えられた文字列のうち、リーダー罫として指定した文字(連続する「…」文字など)のあとに出現する文字を返すAppleScriptです。リーダー罫が文字列中に存在しなかった場合にはそのまま返します。

InDesignの書類からデータを取り出す際に使用したものです。

スクリプト名:リーダー罫文字のあとの文字を取得する
set a to "ひよこさん募集………………………………………………160名"
set b to retAfterRuledLineCharacter(a, "…") of me
b
–> "160名"

set a to "ひよこさんの募集は終了しました"
set b to retAfterRuledLineCharacter(a, "…") of me
b
–> "ひよこさんの募集は終了しました"

–リーダー罫文字のあとの文字を取得する
on retAfterRuledLineCharacter(a, aRulerLineChar)
  if a does not contain aRulerLineChar then
    return a
  end if
  
  
set cList to characters of a
  
set aLen to length of a
  
  
set rList to reverse of cList
  
set rText to rList as string
  
set rOffset to offset of aRulerLineChar in rText
  
  
set resText to text (aLen - rOffset + 2) thru -1 of a
  
  
return resText
end retAfterRuledLineCharacter

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/22 文字列から数字の部分を取り出してリスト化

文字列から、数字の部分を取り出してリスト化するAppleScriptです。

スクリプト名:文字列から数字の部分を取り出してリスト化
set a to "100名(人間12名、ひよこ88名)"

set aList to characters of a

set aResList to {}

set inF to false –アイテムへの取り込みフラグ:初期値=false(取り込まない)
set oneItem to ""

repeat with i in aList
  set j to contents of i
  
set aF to detectOutNumChar(j) of me –aF:現在のキャラクタがNumericかどうかの判定フラグ
  
  
if aF = true and inF = false then
    set inF to true
    
set oneItem to oneItem & j
    
  else if aF = true and inF = true then
    set oneItem to oneItem & j
    
  else if aF = false and inF = true then
    set the end of aResList to oneItem
    
set oneItem to ""
    
set inF to false
    
  else if aF = false and inF = false then
    –なにもしない
    
  end if
end repeat

if oneItem is not equal to "" then
  set the end of aResList to oneItem
end if

aResList
–> {"100", "12", "88"}

–数字範囲外の文字があるかどうかをテストする
–数字の文字以外のものが入っていたらfalse
on detectOutNumChar(testText)
  –ANK文字列(大文字小文字は問わない)
  
set ankChar to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."}
  
  
set _testChar to testText as Unicode text
  
  
ignoring case
    repeat with i in _testChar
      set j to contents of i
      
if j is not in ankChar then
        return false
      end if
    end repeat
  end ignoring
  
  
return true
end detectOutNumChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

02/23 Mac OS X 10.5/10.6上のファイル名/フォルダ名に関するバグ

AppleScriptにおける「パス」について(5)のコメント欄で教えていただいた件を実際に確認してみました。

asbug1.jpg

濁点つき(たぶん、半濁点も)のフォルダを用意して(たぶん、ファイルでも同様)……そのファイル名を取得。ファイル名の1文字目のidを調べると、文字+濁点(or 半濁点)に分離してIDが取得されてしまうというものです。

スクリプト名:AS_bug_check
set aFol to choose folder

tell application “Finder”
  set aName to name of aFol
end tell

set anID to id of first character of aName

–「ふつうのFolder」を選択した場合
–> 12405

–「だくてんテスト」を選択した場合
–> {12383, 12441}–> 「た」+濁点

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

通常、1文字に対応する値が返ってくるところで、リストで2文字分返ってきてしまいます。それぞれ、文字コードの内容をUnicode Checkerで調べてみると……

asbug2.jpg

asbug3.jpg

ご覧のとおりです。

asbug4.jpg

Finderから取得したファイル名/フォルダ名の文字数をカウントする分には大丈夫そう(↑)なのですが……

asbug5.jpg

ファイル名を1文字ずつ分解して(characters of)、IDを取得するとごらんのとおり(↑)です。

12/30 伏せ字文字列を返す

伏せ字文字列を返すAppleScriptです。

以前にAppleScriptエディタ上の選択部分の文字数をカウントして、同一の文字数の「X」に置換するAppleScriptを作成しましたが、それをさらに高機能にすべく作成したのがこれです。

0〜9、A〜Z、a〜zを個別に別々の文字(9、X、x)に置換します。このため、「03-1234-5678」は「99-9999-9999」になり、「This is a pen.」は「Xxxx xx x xxx.」になります。

数値とアルファベットの区別が分ってしまうとまずいケースも多々ありますが、なんとなくそれっぽく伏せ字になっていればよい、という場合には気が利いていてよいのではないでしょうか?

スクリプト名:伏せ字文字列を返す
set a to “This is a pen. 03-012345″
set aRes to retMaskedStr(a) of me
–> “Xxxx xx x xxx. 99-999999″

–伏せ字文字列を返す
on retMaskedStr(aStr)
  set aList to characters of aStr
  
set outStr to “”
  
repeat with i in aList
    set j to contents of i
    
set jID to ASCII number of j
    
    
if jID 48 and jID 57 then
      –0〜9
      
set outStr to outStr & “9″
      
    else if jID 65 and jID 90 then
      –A〜Z
      
set outStr to outStr & “X”
      
    else if jID 97 and jID 122 then
      –a〜z
      
set outStr to outStr & “x”
      
    else
      –上記以外はそのまま出力
      
set outStr to outStr & j
      
    end if
  end repeat
  
  
return outStr
end retMaskedStr

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

12/26 指定文字列の中に指定文字が何回出現するかカウントする

指定文字列の中に指定文字が何回出現するかをカウントするAppleScriptです。

たとえば、「XXX-XXX-XXXXXXX-XXXX」という文字列の中に「-」が何回出現するかを数えたいような場合に使用します。

作り捨てするレベルのAppleScriptなので、何回か作っているかもしれません。

スクリプト名:指定文字列の中に指定文字が何回出現するかカウントする
set aData to “XXX XXXXX XXXXX XX XXXXXX”
set lookUpStr to ” “
set aRes to countSpecifiedChar(aData, lookUpStr) of me
–> 4

–指定文字列の中に指定文字が何回出現するかカウントする
on countSpecifiedChar(aStrData, aChar)
  set aList to characters of aStrData
  
set aCount to 0
  
repeat with i in aList
    set j to contents of i
    
if j = aChar then
      set aCount to aCount + 1
    end if
  end repeat
  
return aCount
end countSpecifiedChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

12/26 連続する文字(たぶんスペース)を1つにまとめる

指定文字列の中から、連続する文字(たぶんスペース)を1つにまとめるAppleScriptです。

姓と名の間にスペースが入っているんだけれど、1つとは限らない。いくつも入ってきている可能性がある……というケースに備えて、連続する文字(たぶんスペース)を1つにまとめます。

スクリプト名:連続する文字(たぶんスペース)を1つにまとめる

set aStr to "XXX XXXXX XXXXX XX XXXXXX"
set aRes to mergeMultipleChar(aStr, " ") of me

–連続する文字(たぶんスペース)を1つにまとめる
on mergeMultipleChar(aStr, aChar)
  set outStr to ""
  
set aList to characters of aStr
  
  
set successF to false
  
repeat with i in aList
    set j to contents of i
    
if j = aChar then
      if successF = false then
        set successF to true
        
set outStr to outStr & j
      else if successF = true then
        –なんにもしないよ
      end if
    else
      set successF to false
      
set outStr to outStr & j
    end if
  end repeat
  
  
return outStr
end mergeMultipleChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/08 AppleScriptの文字列比較(5)〜句読点の考慮/無視

AppleScriptでは、considering punctuation/ignoring punctuationで文字列比較時の句読点の考慮/無視を行うことができるようになっています。

句読点として一般的に用いられる記号は、「、」と「。」ですが、論文などにおいては全角のカンマと全角のピリオドが使われることもあり、これらを句読点として認識するかどうか試してみたところ、OKでした。

スクリプト名:文字列比較5
set a to "かきくけこ"
set b to "かき、くけこ"
set c to "かき、くけこ。"
set d to "かき,くけこ."

–読点「、」が入っている文字列との比較
ignoring punctuation –ピリオドなどの記号を無視する
  if a is equal to b then
    display dialog "Equal 1"
  end if
end ignoring

considering punctuation –ピリオドなどの記号を考慮する
  if a is equal to b then
    display dialog "Equal 2"
  end if
end considering

–読点「、」と区点「。」が入っている文字列との比較
ignoring punctuation –ピリオドなどの記号を無視する
  if a is equal to c then
    display dialog "Equal 3"
  end if
end ignoring

considering punctuation –ピリオドなどの記号を考慮する
  if a is equal to c then
    display dialog "Equal 4"
  end if
end considering

ignoring punctuation –ピリオドなどの記号を無視する
  if a is equal to d then
    display dialog "Equal 5"
  end if
end ignoring

considering punctuation –ピリオドなどの記号を考慮する
  if a is equal to d then
    display dialog "Equal 6"
  end if
end considering

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/08 AppleScriptの文字列比較(4)〜日本語の大文字/小文字

AppleScriptはconsidering case/ignoring caseで大文字小文字を区別/無視できるようになっていますが、日本語における大文字と小文字とは何を指しているのでしょうか?

実際に試してみると「あ」と「ぁ」、「い」と「ぃ」などの関係を大文字/小文字と見なしているようです。

スクリプト名:文字列比較4
set a to "ぁ"
set b to "あ"

if a = b then
  display dialog "equal 1"
end if

considering case –大文字小文字を考慮
  if a = b then
    display dialog "equal 2"
  end if
end considering

ignoring case –大文字小文字を無視
  if a = b then
    display dialog "equal 3"
  end if
end ignoring

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/08 AppleScriptの文字列比較(3)〜濁点/半濁点の考慮/無視指定

AppleScriptで文字列比較を行う際に、濁点/半濁点を考慮したり無視したりできます。

ここまでできているのに、Mac OS X 10.5以降ではひらがなとカタカナを区別できないというあたりが不思議ですが、、、、

スクリプト名:文字列比較3
set a to “ガギグゲゴ” –濁点つき
set b to “カキクケコ”
set c to “はひふへほ” –ひらがな
set e to “ハヒフヘホ” –カタカナ
set f to “ぱぴぷぺぽ” –半濁点つき

considering diacriticals –濁点/半濁点を考慮する
  if a is equal to b then
    display dialog “「” & a & “」と「” & b & “」は等しい(濁点/半濁点を考慮)。”
  end if
end considering

ignoring diacriticals –濁点/半濁点を無視する
  if a is equal to b then
    display dialog “「” & a & “」と「” & b & “」は等しい(濁点/半濁点を無視)。”
  end if
end ignoring

considering diacriticals –濁点/半濁点を考慮する
  if c is equal to f then
    display dialog “「” & c & “」と「” & f & “」は等しい(濁点/半濁点を考慮)。”
  end if
end considering

ignoring diacriticals –濁点/半濁点を無視する
  if c is equal to f then
    display dialog “「” & c & “」と「” & f & “」は等しい(濁点/半濁点を無視)。”
  end if
end ignoring

–これだけ考慮しても日本語のひらがなとカタカナを区別できない(10.5以降)
considering white space –空白
  considering punctuation –ピリオドなどの記号
    considering hyphens –ハイフンおよび全角スペース
      considering case –大文字小文字
        considering diacriticals –濁点と半濁点
          if c is equal to e then
            display dialog “Equal 3″
          end if
        end considering
      end considering
    end considering
  end considering
end considering

considering white space, punctuation, hyphens, case and diacriticals –上記をまとめて1行に書いてみた
  if c is equal to e then
    display dialog “Equal 4″
  end if
end considering

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/08 AppleScriptの文字列比較(2)〜considering, ignoring

AppleScriptの文字列比較で特徴的なのが、比較を行う場合に条件を設ける構文があるということです。それが、「考慮する」というconsideringと「無視する」というignoring。AppleScriptの基本構文として用意されており、1994年(一部には1993年に公開)の誕生以来、標準で用意されてきたものです。

このconsidering/ignoringでは、「大文字/小文字」(case)、「濁点/半濁点の有無」(diacriticals)、「ハイフンおよび全角スペース」(hyphens)、「ピリオドなどの記号」(punctuation)、「空白、改行文字、タブ」(white space)を指定。複数の条件を同時に宣言したり、consideringとignoringをネスティングさせて同時に使用することもできます。

スクリプト名:文字列比較2
set a to “abc”
set b to “C” –大文字にしてみた
set c to ” a b C “ –スペースを入れてみた

–大文字小文字を無視する
ignoring case
  if a is equal to b then
    display dialog “Equal 1″
  end if
end ignoring

–大文字小文字を考慮する
considering case
  if a is equal to b then
    display dialog “Equal 2″
  end if
end considering

–半角スペースを無視する
ignoring white space
  if a is equal to c then
    display dialog “Equal 3″
  end if
end ignoring

–半角スペースと大文字小文字を無視する
ignoring white space and case
  if a is equal to c then
    display dialog “Equal 4″
  end if
end ignoring

ignoring white space –半角スペースを無視する
  considering case –大文字小文字を考慮する
    if a is equal to c then
      display dialog “Equal 5″
    end if
  end considering
end ignoring

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/08 AppleScriptの文字列比較(1)

AppleScriptについて聞かれるのが、文字列比較についての独特な表現についてです。

とりあえず、基本的な文字列比較について挙げておきましょう。

なお、イコールの表記についてはいくつか同義語が定義されており、「同じことを書くのに人によって記法が異なる」という傾向を生み出しています。

「is equal to」「is」「=」の3つがすべてイコールとして機能します。

なまりの強いAppleScriptのプログラムを手本とした場合に、よその人が書いたAppleScriptを見ても理解できなかったりするところです。

本Blogでは、海外のScripterとの交流の中で感じた、なるべく平易で分かりやすい記法を重視していますが、1つだけ例外があります。

不等号や等号付き不等号などにも別の表記方法があり……極力記号を使いたいところですが……これまでAppleScript Studio環境ではそれらの等号付き不等号がコンパイル時にハネられるとか、エラー発生原因になることが多く、UTF-8でソースコードを書けるようになったMac OS X 10.5までは、等号つき不等号を英語的な別の表記で書かざるを得なかった、という歴史的経緯があります。

等号つき不等号については、記号で書いた方が分かりやすいのですが、仕方なく英語的表記で記述していた、ということです。

スクリプト名:文字列比較
set a to “abc”
set b to “c”

–イコールかどうか?
if a is equal to b then
  display dialog “Equal”
else
  display dialog “Not Equal”
end if

–前方一致
if a begins with b then
  display dialog “begins with”
else
  display dialog “Not begins with”
end if

–後方一致
if a ends with b then
  display dialog “ends with”
else
  display dialog “Not ends with”
end if

–部分一致
if a contains b then
  display dialog “contains”
else
  display dialog “not contains”
end if

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/06 テキスト中の任意の順番の文字取り出し Mac OS X 10.4.11への対応

text 3 of ”ABCD” といった処理はよく使っていたのですが、これがMac OS X 10.4.11上ではエラーになることに気付きました。

Mac OS X 10.4.11は「第2のMac OS 9.2.2」とも言うべき存在であり、まだ相当数の実行環境が残っているばかりか、主要アプリケーションでは10.4.11対応をいまだにうたっているものも少なくありません(Office 2008とかiWork 09とかAdobe CS4とか)。

そんなわけで、本Blogでは10.4.11環境での検証を(最初のころは)しつこく行っていました。しかし、だんだん10.5とか10.6上で書いた方が楽になってきて、10.4.11上での確認を怠っていた今日このごろ……たまたま10.4.11上でこの基本的な記法が通らなかったのを見つけ、すぐさま書きかけのプログラムを書き直した次第です。

こういうものを一覧表にしておくと楽なのかもしれません。海外でも見かけたことはありませんが……。

スクリプト名:テキスト中の任意の順番の文字取り出し Mac OS X 10.4.11への対応
set aStr to “0123456-789″

set a to text 8 of aStr –10.5.8や10.6.1ではこれでOKだが、10.3.9/10.4.11上ではエラーに
set b to text 8 thru 8 of aStr –10.4.11への対策を行った記法。10.3,10.4,10.5,10.6で同じ実行結果

log {a, b}

–> (*-, -*)

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

11/06 指定文字列の中に特定の文字が何回出現するかをカウントして返す

指定文字列の中に特定の文字が何回出現するかをカウントするAppleScriptです。

とくにひねりも何もあったものではありませんが、とりあえず。

スクリプト名:指定文字列の中に特定の文字が何回出現するかをカウントして返す
set aStr to "ABCDEFG-AB"
set aRes to countSpecifiedCharInStr(aStr, "A") of me
–> 2

–指定文字列の中に特定の文字が何回出現するかをカウントして返す
on countSpecifiedCharInStr(aStr, aChar)
  set cList to characters of aStr
  
set pCount to 0
  
repeat with i in cList
    if contents of i = aChar then set pCount to pCount + 1
  end repeat
  
return pCount
end countSpecifiedCharInStr

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に