部分がある場合 , そのグループの内容を順 ・・という特殊変数に代入 に $ 1 , $ 2 , $ 3 , します。次の例て、は $ 1 , $ 2 , $ 3 がそれぞれ 時 , 分 , 秒を保持します。この値を後て、使 うことがて、きて便利て、す。 $time もし / / を配列コンテキストて、使うと , ・・などに代入されるはずだっ の $ 1 , $ 2 , た値をリストにして返してくれます。上の 例て、あれば , Fig. 11 ー①のようにすれば $hour, $min, $ sec が時分秒になります ( / / を配列コンテキストて、使うと $ 1 などは設定 されません ) 。このあたりが perl て、の m 〃の 使い方の醍醐味のひとって、す。 〃演算子は普通、、 m / / 〃演算子と呼ばれま す。それは , 〃の前に m という 1 文字を置いた 場合 , / 以外の記号を / の代わりに使うことが て、きるからて、す。時刻の代わりに日付にマ ッチさせたい場合 , たとえば Fig. 11 ー②のよ うに書くことがて、きます。この例て、は / の代 わりに # を使っています。 m / / 演算子によるマッチングは普通英文字 の大文字と小文字を区別します。もしふた つ目の / の後に i という文字を置くと , 大文字 しましよう。 変数の展開が行われます。 List 19 は tem plate. let の内容のうち NAME をコマンド行 perl プログラムの中には chop という演算 と小文字を区別しないマッチングがて、きます。 子がしばしば登場します。これは文字列の /kaoru/ # 偽 引数て、置換したものをファイルに書き出す ” Kaoru ” 最後の文字を切り捨てるという処理をする /kaoru/i # 真 ものて、す (Fig. 12 ) 。 'Kaoru ” ものて、す。 < IN > て、読んて、きたデータには改 s 〃 / の三番目の / の後に g を書かないかぎ 行文字が残っているのて、 , それを取り除き り , s/ 〃は最初の PATTERN しか置換しま たい場合に使います ( ほかの使い方はあまり せん。また , i をつけると m// と同様に大文 見ません ) 。 字と小文字を区別しない置換をします。 文字列の置換は m 〃と似た演算子 s / 〃を s / 〃の値は置換の行われた回数て、す。ある perl を awk 的に使う場合 , 1 行に複数のデ ータを区切って書くことがあります。 Fig. 14 置換を繰り返したい場合 , List 20 のように 使います。 [$VAR = ー ] s/PATTERN/REPLACEMENT/ 行うことがて、きます (Fig. 13 参照 ) 。 1 while のような住所録ファイルは awk の例題とし s / 〃というのがミソてすにの 1 は無見されます ) 。 てよく出てきます。 このデータて、は名前 , 電話番号 , 郵便番 置換の対象はスカラ変数て、なくてはなり 号 , 住所が、、 ; 〃て、区切られています。 awk ません。書かなければ $ が対象になりま て、はレコードを 1 行入力すると自動的にデー す。 s / 〃は文字列の中の PATTERN にマッ チする部分を REPLACEMENT て、置換しま タが区切られましたが , rl ては自前てする必要 perl のそのほかの文字列処理について説明 があります。この仕事をするのが split て、 , す。 REPLACEMENT は、、 " ク内と同様に perl のノヾターンマッチング Fig. 11 Fig. 12 List 19 の実行例 7 % cat template 」 et NAME くん , こんにちは。 早く原稿仕上げてね。 8 % perl saisoku. が kaoru kumi 9 % cat kaoru.let kao 「 u くん , こんにちは。 早く原稿仕上けてね。 Fig. 13 List 20 の実行例 1 0 % perl paren. が ({this is a test} というかっこ ) の [ バランス ] がとれている。 0 K. こっちは ( とれていない } 。 NG. 罟換 字列処理 58 C MAGAZINE 1991 9
特集フレタ系言語研究 TabIe 13 pe 日の正規表現 正規表現 に評価されます。 perl て、は else が対応する if を見失なったりすることはありません ( 必ず 、、 { ドをつけることになっているからて、す ) 。 また , C て、 elseif と書いていた部分は perl て、 は , elsif という予約語を使って書くことにな っています。 elseif や elif て、はないのて、ご注意 繰り返し文は Fig. 9 のような形をしています ( [ ] て、くくられた部分は省略可能て、す ) 。 fo , は C の fo , 文と暠様て、す。 fo , 000h は配列 の要素をひとつずっ変数 VAR ( 省略されると 例によって $ て、す ) にセットして BLOCK を 実行します。最後の形式は 1 回だけ実行され るループとして処理されます。 continue BLOCK が指定されていると 1 回の繰り返し の最後 ( 次の繰り返しの条件判定の直前 ) に それを実行します。 これらの繰り返し文て、は繰り返し本体の BLOCK の中て、 Fig. 10 の式が使えます。 LABEL はループの実行プロックの名前を示 しています。 LABEL が省略されるともっと も内側のループを指します。 last と redo て、は continue7* ロックは実行されませんが , next ては実行されます。 条件判定の前に , 少なくとも 1 回プロック を実行したい場合もあります。この場合の 特殊形式として , do BLOCK while EXPR 力するものて、す。ある文字列 EXPR が正規表 do BLOCK until EXPR が正規表現をある程度知っているものとし 現にマッチするかを調べるには次のように が用意されています。 てメタ文字だけを解説するにとどめます します ( [ ] は省略可能 ) 。 List 17 は sort コマンドを perl て、書いたもの (Table 13 ) 。 CEXPR perl の正規表現て、は、、 \ 〃と記号 1 文字の ー ] /PATTERN/ Ci] 〃という部分は PATTERN 、、 EXPR 組は常にその記号自身を表します。 grep や のマッチング対象を指示しています。上の Emacs などて、はヾ \ ( , \ ) 〃て、グルーピングを 表しますが , perl て、はバックスラッシュなし 例のようにこの部分が省略されると例によ って $ に対してマッチングを行います。 / / 演 の、、 ( , ) 〃て、表します。 算子はスカラコンテキストては文字列がマ perl の三本柱のひとって、ある文字列処理を イ ッチするとき真 , マッチしないとき偽を返 語るのに正規表現によるパターンマッチン します。マッチング対象をヾ = ー〃の代わりに グを忘れるわけにはいきません。 十クて指示した場合には結果の真偽を逆にしま perl に用いられる正規表現は , egrep のも す。パターンの中に ( ) てグルーピングされた List 18 は Subject : て、始まっている行を出 のを少し拡張したものてす。ここては読者 意 味 改行文字 ( \ n ) 以外の 1 文字 示された文字集合のどれか 1 文字 示された文字集合以外の 1 文字 文字列の始まりの空文字列 文字列の終わりの空文字列 単語境界の空文字列 単語境界以外の空文字列 直前の式の n 回以上 m 回以下の繰り返し (), m は 1 桁以上の数字 ) 直前の式の n 回以上の繰り返し 直前の式の n 回の繰り返し 直前の式の 0 回以上の繰り返し ( { 0 , } と同じ ) 直前の式の 1 回以上の繰り返し ( { 1 , } と同じ ) 直前の式があってもなくてもよい ( { 0 , 1 } と同じ ) 式のグルーピング。 \ n で参照するため , ーの範囲の限定 , 繰り返しの単位を指定するためなどに使う 選択 第 n グループの内容 ( n は 1 から 9 の 1 文字 ) ナル文字 ( \ 000 ) 文字の 8 進数表現 空白文字 ( [*t*n*f*r] ) 空白文字以外 英数字と \ w でないもの 数字 非数字 [a-chx] ta-z] YB {n,m} {n} 十 ( 式 ) c 0 c cn U) -o grep もどき 1 8 List while ( ◇ ) { print if (/ASubject:/) : 1 り 00 正規表現 ヾターンマッチング 特集フィルタ系言語研究 57
てその大きさを事前に宣言する必要があっ たが , フィルタ系言語て、は配列も宣言せず に利用て、きる。配列は使えば使っただけ動 的に領域が確保される。 フィルタ系言語の特権というわけて、もな いが , 本稿て、紹介する perl や awk, python は連想配列という機能を持っている。これ は文字列によってインデクスされる配列の ことて、ある。 perl て、は次のように数字て、イン デクスする。もちろん通常は配列も使える。 $x [ 10 ] $x [ 11 ] ” asdf ” しかし , 次のように文字列をインデクス として利用することもて、きる。 $x{'saito'} yasushi' $x{'suzuki'} 'hiroshi' perl て、は , 性能上の理由からか数字て、イン デクスされる通常の配列と連想配列を書き 分けなければならないが , awk や python て、 はすべての配列は連想配列として扱われる のて、どちらも var [ 10 ] , var ['tako'] のよ うに書くことがて、きる。 perl て、はさらに連想配列を dbm ( 簡単なデ ータベース管理ライプラリ ) とリンクして , データベースファイルに連想配列を利用し てアクセスて、きる機能も提供している。 想配列 み込み関数 32 C MAGAZINE 1991 9 をつけるか , d 。関数名 (... ) と組み込み関数 ことはて、きるが , 呼び出すときには頭にヾ \ & 〃 たとえば , perl て、は自分て、関数を定義する 合もある。 り , あるいはまったく用意されていない場 自分て、関数を定義する機能は不十分だった にという考えの下に用意されている。逆に いる。短いプログラムを簡単に書けるよう 組み込み関数 / 手続きが豊富に用意されて とは異なった呼び出し方が必要て、ある。 また , データ構造を自分て、定義する機能 は不十分て、ある。というより , 文字列と文 字列の配列以外のデータはサポートされて 。ほかの複雑なデータ型を利用する にはそれを何らかの形て、文字列や文字列配 列に変換する必要がある。たとえば awk て、 は多次元配列は , 各インデクスを文字列と して連結した連想配列として実現される。 f00 ["saito","suzuki' ] は , f00 ["sait0*034suzuki"] のように間に、、 \ 034 〃という ( 普段はあまり 使われない ) 文字列を間にはさんて、 , 一次元 配列に変換する。 perl て、も同様のテクニック を使わなければならない ただし , 後て、紹介する python はリストを 持っている。 例外的な機能が多い。多くの組み込み手 続きて、は引数を省略することがて、き , 省略 したとき挙動は手続きによってさまざまに 異なる。 awk て、はパターンに対応するアク ション部を省略したときは行全体をプリン トすることになっている。これなどは例外 的な機能の例て、ある。 perl て、は , さらにさまざまな例外動作が用 意されており , たとえばファイルから 1 行読 み込む手続き <handle> は , while 文の条件 節に使った場合に限って結果を、、 $ 〃 う暗黙変数に格納するとか , 普通の組み込 み手続きて、は引数を省略したときは , 、、 $ 〃 あるいは、、 @ 〃という変数の値が使われる のに対して , shift という配列の要素をずら す手続きて、は引数を省略すると ARGV( プロ グラム自身に渡されたコマンド行引数を保 持するグローバル変数 ) をシフトしてしまっ たり , split という文字列を分解する手続き て、はパターンの種類によっては予測しがた い動作をしたりと , かなり perl に慣れた人て、 例外的機能 もとまどう例外的動作が多量にある。 これらの例外的機能をうまく使えばプロ グラムを極端に簡潔に書けるが , 予期され ていない使い方をすると何をやっているの か作者以外には ( ときには作者にすら ) わか らないプログラムとなってしまう。 正規表現は , もともと正規言語という言 語が受け入れるパターンを文字列として表 現するために考えられた表現方法て、 , それ をテキスト検索のパターン指定に応用した ものて、ある。 正規表現にはいろいろバリエーションが あるが , egrep, awk, perl, python などて、 は次のような記法を使う。以下にあげる特 殊文字以外の文字はその文字自身を検索す るために使われる。たとえば abcd は abcd と いう文字列にマッチする。これは正規表現 をサポートしない普通のテキスト検索と同 じて、ある。 ″ ( ピリオド ) ピリオドは任意の 1 文字にマッチする。た だし日本語に対応していない正規表現処 理手続きて、は , 漢字は 2 文字とカウントさ れる場合もある ( つまりこの場合は任意の 1 バイトにマッチする ) 。 [character-list] character-list 中の任意の 1 文字にマッチ する。たとえば , Cabcdst] と書くと , a, b, c, d, s, t のどれか 1 文字にマッチする。 , Ca-z] のように書くこともて、 見表現 う書くと a, b, き , , z の 26 文字の うちのひとつにマッチする。同様にたと えば CA-Za-z0-9 ] と書いて , 大小アル ファベットと数字 , 、、〃のいずれかにマ ッチさせる , といった表現も使うことが
特集フレタ系言語研究 て、きる。 [character-list] ] に似ているが , 逆に character- list の中に含まれていない文字列にマッチ する。 * ″ ( アステリスク ) 直前のパターンの任意回数 ( 0 回以上 ) の繰 り返しにマッチする。 たとえば , [ 0 ー 9 ] * と書く一と , 数字 ( つまり [ 0 ー 9 ] ) の 0 回以上任意回数の繰り返し , 0 , 0234 , 9872 などにマッチする。 * クと書 くと , 任意文字の任意回数の繰り返し , 要 は ( 空文字列を含む ) 任意の文字列にマッチ することになる。、、 a. * z" は a て、始まり z て、終 わり , 中に任意の文字列を含むような文字 列 , az, aqwerz, apoqwieurz などにマッチ 、、 * 〃を使うとかなり広範なパターンを表現 することがて、きる。たとえば , C の変数名 , 関数名は , 最初の文字がアルファベットま たはゞ そして 2 文字目以降はアルファベ , 数字の繰り返しということにな っているが , これは CA-Za-z ] CA-Za-z 0 ー 9 ] * というパターンとして表現て、きる。 任意のパターン ) は , XX * に等しい 上の繰り返しにマッチする。、、 X 十 "(X は * に似ているが , 直前のノヾターンの 1 回以 “十″ ( プラス ) にマッチする。 しにマッチする。、、 ab?c" は ac または abc 直前のパターンの 0 回または 1 回の繰り返 ″ ( クエスチョン ) 頭に abc がある場合に限ってマッチに成功 行頭にマッチする。たとえばは行 する。 行末にマッチする。、、 abc $ ′′は , 行末に ab c がある場合に限ってマッチに成功する。 (patterm patternn) 各論てすけど . . subsection [fumi] ふみふみ . section 各論です て詳細を解説しています . . ref fumi こではふみふみについて概要を説明します . . subsection ふみふみとは何か この章では序論をのべます . . section ますは序論です Fig. 1 サンプルテキスト 身を検索したい場合には前に、、 \ 〃をつけ 上にあげた、、 * 〃、、〃などの特殊文字自 な働きを持っている。 とめてひとつのパターンとして扱うよう つまり , (... ) は , その中のパターンをま にマッチする。 空文字列 , abc, abcabc, abcabcabc, ・ マッチする。たとえば , 、、 (abc) * クは , の場合 , .. 全体の任意回数の繰り返しに .. ) * のように書くこともて、き , sazae のどれかひとつにマッチする。ま awabil sazae) は , tako, ika, awabi, にマッチする。たとえば , (tako lika ー patterm, patternn の中のどれかひとつ いう文字列自身にマッチする。 おおむね以上の機能を持っていれば「正規 表現をサポートしています」ということがて、 きるが , 実際には , 最後の (... 匚 .. ) 機能 はサポートしていないプログラムが多い ほかのプログラムて、は多少変わった記法 を用いる場合もある。 grep や emacs て、は (.. . 匚 . ) の代わりに \ (). \ 匚 . \ 匚 . \ ) を用 いる。また , perl て、は , * 〃をさらに強力 にした {X,Y} というパターンをサポートし ている。 {X,Y} は直前のパターンの X 回以 上 Y 回以下の繰り返しにマッチさせることが て、きる。 X を省略すると 0 , Y を省略すると と見なされるのて、 , これを使うと、、 * 〃は 、、 ? 〃は { 0 , 1 } と 表現て、きる。 正規表現の練習として下の表現がどのよ うな文字列にマッチするかを考えてみよう。 このパターンは次から作るサンプルプログ ラム中て、多少違った形て、使われている。 \. (subl subsubl )sætion ( \ [ に \ ] ] * \ ] ) 特集フィルタ系言語研究 33
特集フレタ系言語研究 算子と同じような仕組みて、行います。 $kaoru 25 ; $kumi ” shikushiku ” $hideki 十 = 14 , 定数 cat もどき (mycat. pl) List 1 5 while ( ◇ ) { print; 1 亠りっ 0 準工ラー出力を表すものて、 , あらためてオー かにも、、 \ n 〃 , 、、 \ t 〃 , 、、 \ 033 〃など C のそれ プンしなくてもあらかじめ用意されています。 とほば同じものが使えます。 ファイルハンドルを使った出力は print 文 引用符として ( シングルクオート ) を perl の定数には数値定数 , 文字列定数 , リ など出力文に対してハンドルを指示してや 使うと , 変数の展開 , スト定数などがあります。数値をそのまま ノヾックスラッシュの 解釈は行いません ( ただし \ ' 〃は、、 ' ク自 ればよいのて、す。今まて、 , 書けば数値定数になります。 print "TotaIis : $total*n" 身 , 、、 \ \ 〃は、、 \ 〃自身を表すと解釈されま 1 と書いていたのは , 実は , す ) 。、、 ' $ 20 ' クは、、 $ 20 〃という 3 文字 , 、、 ' \ n ' 〃 3 .14159 は、、 \ 〃と、、 n 〃の 2 文字の文字列を表します。 print STDOUT "T0taIis . 6 . 63e ー 34 引用符として、、ン ( バッククオート ) を使 $total*n" 0xffff の STDOUT が省略された形だったのて、す。 ったものは特別て、す。文字列の中身は 文字列定数は文字列を引用符て、くくって STDOUT と出力するデータの間にコンマが の場合と同じようにまず変数が展開されま 己述しますが , その引用符の種類によって ありません。 perl のファイルハンドルはプロ す。そして , その内容をコマンドとみなし 解釈が少し異なっています。 グラム中て、はただ名前がばつんと記述され て子プロセスを起動します。子プロセスの ( ダブルクオート ) を使う 引用符に ることがままあります。最初は気味悪いと 標準出力が文字列の内容となります。この と , その中にある変数と配列変数の値を文 思うかもしれませんが , いずれ慣れて、しょ 例て、は ls の出力結果が文字列の値てす ( ls の 字列中に開きます。 List 14 の、、 Total is : 出力した改行文字も残っていますね ) 。 $totaIYn" は変数ヾ $ total 〃の値が 10 の場合 ファイルハンドルをオープンするには , には、、 TotaI is : 10 \ n 〃になるわけて、す。 叩 en ( ) 文を使います ( Fig. 5 ー① ) 。ここてハ この展開はプログラムの実行中文字列が評 ファイル八ンドル ンドル OUT や APPEND は引用符てくくられ 価されるたびに行われます。 C て、の sprintf たり $OUT のような記号がついたりはしませ ( ) の使い方の多くは , perl て、はこの機能て、 ん。 perl のファイルハンドルはわかりやすい perl て、のファイル入出力はファイルハンド 間に合ってしまいます。 ように大文字て、書くのが習慣になっていま ルを通して行われます。 List 14 に出てきた 、、 $ クや、、 @ 〃自身を文字として扱ってほ STDIN は標準入力を表すファイルハンドル しい場合にはヾ \ ク ( バックスラッシュまた す。 叩 en の第二引数にはファイル名を書きま て、す。 STDIN, STDOUT, STDERR の三つ は円記号 ) て、エスケープします (Fig. 4 ー① ) 。 すが > クて、始まっていると出力用 > > 〃 のファイルハンドルは perl の標準入出力 , 標 ノヾックスラッシュによるエスケープは , ほ Fig. 6 List 15 の実行例 Fig. 5 perl のファイル八ンドル outfile へ出力する八ンドル OUT ① open (OUT, ">outfile") : 5 % cat ika logfile へ追加する八ンドル APPEND open(APPEND, ">>logfile") : ika ika ika 変数 $file にファイル名が入っている open (DAT, ">$file") : ika douyou. 6 % perl mycat. が takO ika uni ファイル address の読み込み ② open(ADDR, " く address") : open(ADDR, "address") : 上と同じ --this is the content Of tako- $file にファイル名が入っている open 0 N, $file) : --end of tako-- ika ika ika ③ open(NKF, "nkf -x $file に ) : nkf - x に $ f ⅱ e を渡し , その出力を入力用八ンドル NKF から読む 出力用八ンドル OUT の出力は子プロセス厄 ss に入力として渡される ika douyou. open (OUT, " lless") : Noumiso UNI ni natchau- 1 三ロ 特集フィルタ系言語研究 53
特集フレタ系言語研究 もしこの条件が成り立っていなければ , コ ードはさらに長くなってしまうだろう。 sed のスクリプト (List 6 ) は , それと比べ ると信じられないほど短い。このスクリプ トて、は , s コマンドによって置換を指定し , オプションとして g をつけることによって , ひとつの行に対して複数回の置換を行うこ とを指示しているだけだ。入出力処理など の記述は不要て、ある。 awk のスクリプト (List 7 ) は sed に似てい る。ただし , s / ・・・ / ・・・ / g の代りに gsub(/ ・・・ /, ・ " ) というシンタックスを使うほか , 出力 処理を行うための print を明示的に書く必要 がある。とはいえ , 何を出力するかは省略 て、きるのて ' , 記述の手間はとくに増えたと はいえない perl のスクリプト (List 8 ) も sed, awk の ものに近いが , 出力を行う print のほか , 入 カデータがある間は入力を繰り返すという awk, perl て、それぞれ作成した (List 5 , 6 , 間よりもディスクのアクセスタイムのほう 意味の while ( < > ) を書かなければならな 7 , 8 ) 。 が長いため , むしろ圧縮したほうが読み出 い。強いていえば , この点がめんどうて、ある。 し量が減る分だけ速くなっている。 この例て、の開発効率は , 以上のように この結果を考えると , ノートパソコンな C のみが著しく劣り , 三つのフィルタ系言語 どのフロッピーベースのマシンて、フィルタ 間のはあまり変わらないといえる。 スクリプトの長さは TabIe 5 のとおりて、あ 示言語を使う場合は , 常に処理系を圧縮す る。 C 言語によるコード (List 5 ) は比較的長 べきだろう ( 遅い CPU を使っているため , 展 い。文字列をファイルから読む込み , 文字 開時間が極端に長くなる , という場合は別 列関数を使って文字列から句読点を検索し , だが ) 。ハードディスクを使っている場合て、 これらの句読点変換プログラムを以下の その内容を書き換え , それを出力する , と も , それほど頻繁に使わない処理系につい 条件て、走らせて , それぞれ実行時間の実時 いう処理を , すべて細かく記述する必要が ては , 圧縮をかけておいたほうがよいと思 間を測定した。 あるからて、ある。また , 文字列の書き換え マシン : PC ー 9801VX2 ( 80286 8MHz) の箇所て、は , 書き換える部分文字列の長さ 対象データ : RAM ディスク上に置いた が書き換えの前後て、ともに 2 バイトて、あるこ 25K バイトのテキストファイル (lha のマ とに依存した技巧的なコードを使っている。 TabIe 5 スクリプトの長さ 処理系 ファイル名 kutouten. c kutouten. exe kutouten. sed kutouten. awk kutouten. が sedC 記述した kutouten. sed List 6 1 : s/o /. /g awkC 記述した kutouten. awk List 7 1 よりんっ 0 4- LD gsub()o / , " pr int perlC 記述した kutouten. List 8 ・ 1 ( 0 0- 1 人っな -4- ロ 0 開発効率 実行速度 簡単な応用例による まず , 日常的によく使われるような , 単 純な文字列置換処理にこれらの処理系を応 用した例て、比較する。 こて、は , 文中の句読点「。」 , 「 , 」をそれ ぞれ「 . 」 , 「 , 」 ( 1 バイト文字 + 1 バイトスペ ース ) に変換する処理を考える。この処理を 行うプログラム kutouten を , C, sed, ファイルサイズ 627 バイト ( ソース ) 4824 バイト ( オプジェクト ) 22 バイト 53 バイト 55 バイト sed awk perl 特集フィルタ系言語研究 43
特集フレタ系言語研究 五ロキ」門 グつのる ンなグす にン説 ラうミ解 グよラら 判よ使ム の今陸ラ 昨グ Q ロ かはプ 「前でル 名稿プ PA RT—=-O 則田薫 perIÄ門 機能て、す。 のすべての活動の原点とさえいわれていま これら強力な文字列処理の対象となるデ す ) からのようて、す。 さて , perl とはいったいどういう言語なの ータを取り込むために , perl はファイルの読 て、しようか。 perl の得意分野は大きく三つ。 み書き , 子プロセスによるコマンド実行 ( と 文字列処理 , ファイル処理 , そしてプロセ その出力をファイルとして読み込む手段 ) な 、、 pe 卍 ( 「ば一る」と発音します ) というのは あまり聞き慣れない単語て、すね。何かの頭 ス処理て、す。 どの機能を持っています。 文字なのて、しようか ? 今年 1 月に出版され 文字列処理として perl が得意としているの また , 内容に関知せずにファイルを複製 したり , 名前変更を行ったりするファイル たばかりの TProgramming Perl 』 (Larry は , ( 「抽出」を名前の一部に持っていること が示すように ) 大量のデータから必要な部 管理や , fork や wait, kill などを含むプロセ WaII, RandaI Schwartz 共著 , O'ReiIIy & 分を取り出し , 加工することて、す。正規表 ス管理も perl のおもしろい部分て、すが , 今回 Associates, lnc. , 以下「 perl 本」と呼びます ) に は入門ということて、割愛しました。 現によるパターンマッチング , 文字列置換 よると、、 PracticaI Extraction and Report Language" のことだそうて、す。「実用的抽 などがこれに当たります。これまて、 grep, 出・報告言語」とて、もいったところて、しよう sed, awk といったフィルタ系言語がコマン 起動してみよう か。この名前は Larry Wall の perl 作成の動 ドを使って行っていたような仕事を , perl は 機が遠くにある実験システムの状態レポー 自分て、こなしてしまいます。て、は「報告」と トを自動的に作成するためだったことを表 はなんのことて、しようか。 perl の出力文て、目 C 言語の教科書の最初に必ずといってもよ を引くものに、、 format" があります。これ いほど出ている例 , 、、 He110 World" を perl しています。 は COBOL の PICTURE や BASIC の 流に書くと List 13 のようになります。 # 「、、 and 〃を大文字にして、、 pearl" という名 前にすれば真珠になったのに」と思うかもし PRINTUSING 文に似たものて、 , 出力したい include とか BEGIN のようなめんどくさいも れません。実際 , 完成当初は pe 義 rl と呼ばれ データを人間にわかりやすい形に整形する のは見あたりません。 ていました。 WaII が pe rl から a を抜いて perl h owdy. が にした理由には , すて、に PEARL という名前 のグラフィック言語があったこともありま すが , おもに pe rl は 5 文字もあって打つのが めんどくさかったにの「めんどくさい」カ第 11 とは List 1 3 1 : print ” How , world! }n ” 特集フィルタ系言語研究 51
特集フレタ系言語研究 字列とファイルの 1 行を同等に扱うことが多 数 / 文字列などにデータが区別されるが , フ い。テキストファイルは行単位て、意味を持 イルタ系言語ては演算の種類に応じてデー っている場合が多いが , そのようなファイ タを自動的に要求される型に変換してしま ルの処理に適応している。逆に行がそれほ う。たとえば , 文字列に対して算術演算を 昔のパソコンて、は電源を入れるとまず どの意味を持っていない場合 ( C のソースフ 直接ほどこすことがて、きる。 BASIC が立ち上がった。 BASIC を使えば , ァイルなど。また , TeX や roff て、書かれた文 perl て、は , 取りあえずはその機械の持っているグラフ 書も改行コードにはあまり意味はない ) や , ィックやファイル入出力などのハードウェ そもそもファイルがテキストとして解釈て、 print $x ア機能をすべて利用て、きた。ちょっとした きない場合 ( * . exe ファイルなど ) の処理は の結果は 1468 となる。また , 逆に数値を文 仕事をするには付属の BASIC はたいへん便 難しくなる。 字列として扱うこともて、きる。 利に使えた。本特集て、取り上げるフィルタ 1234 . 345 ; 系言語は MS-DOS や UNIX における BASIC print $x ・ のような役割を持った言語て、ある。 の結果は、、 1234345 〃となる。 〃は文字列 フィルタ系言語は , MS-DOS や UNIX に 正規表現を使ったパターンマッチを多用 を連結する演算子て、ある。 よく現れる均一なテキストファイルの処理 する。正規表現十て、解釈て、きるファイルな このようにある値が数値として扱われる に関してはほとんど万能の言語て、ある。そ らば簡単に処理て、きるが , 本質的に正規表 か , 文字列として扱われるかは , その値が して MS ー DOS や UNIX て、は仕事の大部分が 現て、は解釈て、きないファイルの処理は難し 利用される文脈によって変わる。 そのようなファイルを通じて行われるのて、 , 。たとえば , C の字句の解釈 ( ソーステキ 値の解釈が文脈によって変わると , 変数 い フィルタ系言語を使いこなせれば , 実際 MS ストから予約語 , 関数 / 変数名などを抜き出 名 , 演算子名の入力間違いといった不注意 ー DOS や UN Ⅸて、の仕事の大部分がて、きる。 す ) は正規表現て、書ける。だから , C プログラ によるミスが検出しにくくなる。たとえば もちろん , テキスト処理に特化している ム中の予約語だけを太字て、表示するフィル C て、、、 1234234 〃という文字列を得ようとし だけに C のような汎用言語と比べて , ずっと タなどは簡単に作ることがて、きる。 て strcat(1234, " 234 " ) というプログラムを 簡単にプログラムを書くことカイきる。さらに しかし , C の文法は正規表現て、は解釈てき 書くと , プロトタイプを正しく宣言してさ テキスト処理以外のシステムに立ち入った ないのて、 , たとえば C のソーステキストの中 えいれば , コンパイル時に 1234 が文字列て、 から関数定義を行っている場所を抜き出す ないという型工ラーを検出することがて、き 処理がて、きるように拡張された言語もある。 というような処理は難しい るが , perl て、文字列の連結をしようとして , perl はプロセス通信なども含めて UNIX の システムコールのかなりを直接扱えるのて、 , ” 1234 ”十” 234 ” のようなプログラムを書いても 1468 という いよいよ C を使う機会が少なくなるといって も過言て、はない 値が返されてしまう。 インタブリタ型言語て、ある。簡単にプロ 反面 , 同じことを行わせるのに書かなけ ればならないプログラムの量は確実に減る。 グラムを書いて使うことがてきるが , 代わ フィルタ系言語ては C のように何千行 , 何 りにスピードは遅い。とはいっても , 通常 のテキスト処理は CPU の速度よりも I / O の速 万行といったプログラムを書くことはあま 度のほうがポトルネックになることが多く , フィルタ系言語はいくつかの共通した特 り考えられていない ( 書く人はいるが・・・ 徴を持っている。 そのような場合には多少 CPU 側が遅くなっ プログラムの厳密さを損なってもよいから ても全体のスビードにはあまり影響がない 簡単にプログラムが書ける道を選んだとい えるだろう。 また同様の考えの下に , 変数を利用する 変数 / 関数に型がない 文字列処理能力は強力て、ある。その反面 にあたっての宣言が不要の場合が多い あまり強力な数値演算能力は持っていない 変数 / 関数に型がないことが多い。 C など BASIC と似ているが , さらに徹底してい る。 BASIC ては配列を利用する場合に限っ また , ファイル入出力を行単位て、行い , 文 の汎用プログラム言語ては整数 / 浮動小数点 五ロ 系 タ イ フ ” 1234 ”十” 234 ” 正規表現 ンタブリタ 特 の 五ロ 系 タ 強力な文字列処理能力 特集フィルタ系言語研究 31
S 日 0 プログラミング Fig. 4 メニュー画面 Fig. 5 窓口会計処理画面 簡易卩 0 S 窓口会社処理 処理を選択して下さい カド名価 人数 タの追加 商品デ 2. 商品データの修正 3. 窓口会計処理 燼 S を入力したい場合には , 商品名の入力時に List 4 は商品コードから商品名 , 単価など れている。しかしこのディスクは 5 インチ 2 ソ〃を入力する。すると個数入力のルーチン の情報を獲得する関数てある。本プログラ HD< あり , かっ MS ー DOS フォーマットもの に入るのて , そこて個数を入力する。ひと ムはもともとマルチューザ用に作成してい なの <,SPARCLT ないし SUN ワークステ つの商品の入力が終了すると , SP300 に商品 るのて , データを探索中は ISAM をロックし ーションて使用するためには , 媒体変換お コードと価格が印字される。商品名の入力 ている。この役割を担っているのが LKISA よびコンバートが必要てある。まず , 3.5 イ 時に一キーを空打ちすると終了とな ンチ 2DD フロッピーを MS ー DOS 上てソ 9 クつ M 関数てある。 り , SP300 に総合計が印字される。窓口会計 List 5 は , 外部変数を初期化する関数。 fld き <FORMAT する。次に MS-DOS 上てこ 処理自体を終了したい場合には , 商品名入 。 rd はフィールドの順序を指定する変数て のフロッピーにファイルをコピーする。最 カ時 * 〃を入力すればよい 後にワークステーション側 <MS-DOS/SU ある。 fldtyp は , 文字型 , 数値型などのフィー ルドのタイプを指定する変数てある ofldlen は NOS のコンバータを起動し , このフロッピ 以上の処理を行うには , あらかじめデー 各フィールドの長さを指定する変数てある。 ーから同ファイルを読み込めばよい。 SPA タベースに各商品に関するデータを入力し RCLT の場合には , 以下のような手続きて ておく必要がある。メインメニューにおい 付録ティスクの 行う。 て商品データの追加を選択すると , 商品デ 使用について % /bin/su ータ入力画面になるのて , 商品コード , 商 Password : ( パスワードを入力 ) 本プログラムは , 付録ディスクに収録さ 品名 , 売価などをそれぞれ入力する。 Fig. 6 markndb. P「2 プログラム 次のソースプログラムを参照してほしい List 1 はデータベースの定義に関する定数を 定義しているヘッダファイルてある。 List 2 は外部変数を定義しているヘッダファイル てある。 List 3 は main 関数てある。 markndb. pr2 (Fig. 6 ) は , データベースを定義しているパ ラメータファイルてある。画面表示に関し ては , curses ライプラリを使用している。ま た OPENISAM など大文字だけの関数は , c ー tree の関数てある。 utextke2 は , 前回紹介 した罫線表示関数てある。 12 6 4 3 0 marcust. dat 144 3 marcust. idx 8 0 8 0 4 20 114 16 0 1 marhin. dat 80 5 marhin. idx 10 0 10 0 2 marden. dat 50 6 marden. idx 4 0 4 3 7 16 8 0 8 28 10 0 1 2 8192 0 0 1 1 8192 0 8192 1 3 0 0 0 1 8192 1 1 32 1 0 32 1 0 1 0 8192 1 1 32 1 0 2 8192 1 1 0 1 0 32 1 0 32 1 0 1 1 12 14 SPARC LT プログラミング 107
ーマイクロ、カト lnformation from C0mpiler Makers Microsoft BASIC V 部 . 7.1 たり , サイズ変更することが可能 プロフェッショナルユーザ向け 字列配列 , テンボラリ文字列 利用して大規模なプロクラムを作 てす。 2. プロシージャレベルの文字列 の BASIC として , Microsoft BASIC 成していました。 BASlC7.1ては , オーバーレイ方式を利用して , 最 配列が動的になるか静的になる 3. COMMON< 宣言された文字列 Ver. 7.1 ( 以下 BASIC7.1) の発 大 16M バイトのプログラムを作成 , かは , 配列の宣言方法て変わりま 4. プロシーシャレベルて宣言され 売を 6 月下旬から開始しました。今 す。デフォルトては , 定数の添字 実行てきます。 回は , BASIC7.1 のメモリ関係情報 た文字列配列 オーバーレイを指定するには , を使って次元を決めた配列は静的 far 文字列を利用する場合は , 生 を紹介します。 LINK ユーティリティの実行時にオ 配列となります。 成コードが大きく , かっ , 実行ス コンバイルされた ーバーレイにするモジュールをカ ビードが低下します。 EXE とメモリ M とメモリ ッコ ( ) クて囲みます。カッコの そのため , QuickBASIC4.5 と 中のモシュールがひとつのオーバ 同様 , near 文字列もサポートして ーレイになります。 データベースは大量なデータを います。 30K バイト程度しか文字列 字列と字列 たとえば ,Fig. 1 の LINK コマン 扱うため , メモリを多く消費しま を扱うことはてきませんが , コン ドライン上から実行すると , A—I パクトかっ , 高速な EXE ファイル す。 の 7 個のオプジェクトファイルから MSOS / 2 のプロテクトモードて Quick BASIC4.5 ては , mROUP を生成てきます。 実行する場合はとくに大きな問題 3 個のオーバーレイを生成します。 QuickBASIC Extended Ver ( 最大 64K バイト ) の中にすべての可 はありませんが , MS-DOS< 実行 (B 十 C), (E 十 F), ( I ) がオーバ sion( 以下 QBX)< は , far 文字列 変長文字列データを格納していた ーレイモジュールてす。残りのモ する場合 , メモリの利用方法が実行 ため , 文字列を大量に扱うプログ のみをサポートしています。 シュールとランタイムコードがメ スピードに大きく影響を与えます。 ラムを作成すると , 文字列領域不 S 川 SK オー / ←レイ モリに常駐されています。 ISAM ては , データ用のメモリと 足が頻繁に発生していました。 各オーバーレイモジュールのサ して 2K バイト単位のべージバッフ BASIC7.1 ては , 大量の文字列を イズは , 最大 128K バイトて 64 個の アを使います。 ISAM を利用する場 BASIC7.1ては , EMS メモリ 扱えるように , far 文字列をサポー モジュールを利用てきます。 128K 合 , 最低ても 6 べージが必要となり トしています。 BASIC7.1 ては , 以 や , DISK を利用したオーバーレイ バイト以上の EMS の空きメモリが プログラムを作成することが可能 ます。 下の四つのグループごとに 64K バイ なければ , 自動的に DISK オーバー トを文字列領域として利用てきま てす。 バッフアが十分にないとディス レイとなります。一般的に , オー クとメモリ上のバッフアの間て頻 従来 , MS-DOS の 640K バイトの す。 バーレイを利用する場合 , 実行速 メモリの限界を意識し CHAIN を 繁にスワップが発生するため , 速 1. モジュールレベルの文字列 , 文 度が低下することに注意が必要て 度が低下します。 ューザメモリを圧迫せずに高速 す。 にデータベースを扱うため , MS- 動的配列と静的配列 DOS 上ては ,EMS メモリの利用が ポイントになります。 配列のためのメモリ確保のタイ ミングを制御することによって , プログラムのメモリをより効率的 に管理てきます。 QBX は , 工デイタやデバッガな 配列のためにメモリを確保する どの統合環境を利用するため , 約 のは , プログラムのコンパイル時 , 340K バイトのメモリを必要としま もしくは , 実行時てす。コンパイ ル時に確保する配列を静的 ( スタテ す。そのため , 大きなプログラム の実行のためのメモリを確保てき イク ) 配列 , 実行時に確保する配列 を動的 ( ダイナミック ) 配列と呼び ない場合があります。大きなプロ グラムを QBX 上て実行てきるよう ます。動的配列は実行中に解放し LINKA 十 (B 十 c) + (E 十 F) 十 G 十 (l) TabIe 1 nea 「文字列を使用 引数 fa 「文字列を使用 FRE(a$) その文字列変数を含むセグ DGROUP メント FRE ( " リテラル文字列 " ) テンボラリ文字列領域 DGROUP FRE(O) DGROUP lllegalfunction call FRE(-I) fa 「メモリ fa 「メモリ FREG2) スタック領域 スタック領域 拡張 ( EMS ) メモリ 拡張 ( EMS ) メモリ FRE(-3) Q 日 X とメモリ 148 C MAGAZINE 1 1 9