Top  > 雑記帳  > キーワード別  > 正規表現

正規表現に関する雑記

  2002年01月15日(火)   PCRE
C++ Builder 5でPCREを試してみました。 
 
■ POSIX風 
------------------------------------------------------- 
regex_tとregmatch_tという二つの構造体のエリアをプログラム側で用意しなければいけません。流れとしては、regcomp → regexec → regfree です。 
 
a(b.c)d の( )の数がregcompでregex_tの中のnsubに返ってきます。0番目のregmatch_tの中にマッチした全体のstart/endの位置が入り、$1が1番目という感じです。何故かその後ろに-1/-1のペアが入ってくるので、多めにregmatch_tを用意していないとダメみたいです。 
 
■ オリジナルのPCRE 
------------------------------------------------------- 
流れとしては、pcre_compile → pcre_info → pcre_exec → pcre_free という感じです。POSIX風の時とインターフェースが変わり、今度は pcre という構造体のエリアは pcre_compile が作ってくれます。( )で括った部分を受けるエリアは自分で用意しないといけないのは同様ですが、それはただのintの配列です。POSIX風の時のnsubにあたるものは pcre_info で取得しますが、(その数+1)*3 ぐらい用意しておけ、ということがHelpに書いてあります。本体が作業域でお使いになるそうです。 
 
また、POSIX風の時のとは違って pcre_version でバージョン情報を取得できます。すると「2.01 21-Oct-1998」です。何だか古そう・・・ということで、 
 
■ 今のバージョンのPCRE 
------------------------------------------------------- 
netで捜すと今のバージョンは3.8までいっています。そこで、それをダウンロードしてみました。 
 
GNUWin用のbinのアーカイブからpcre.dllを、libのアーカイブからpcre.hとlibpcre-bcc.libを解凍します。bccという名前通りBorland用のimport libが用意されています。 
 
とりあえず、pcre_info を pcre_fullinfo に変え、pcre_execの引数の変更にあわせてソースを修正し、プロジェクトにlibpcre-bcc.libを追加すると、ちゃんとコンパイルができました。カレントにpcre.dllを置いて実行してみると、バージョンの表示は「3.8 18-Dec-2001」となりました。その他の動きの2.01との違いはよくわかりません。 
 
ちなみに 
2.01の時のテストプログラムのexeのサイズ:384k  
3.8の時のテストプログラムのexeのサイズ:366k  
3.8のpcre.dllのサイズ; 47.4k 
でした。 
 
【今日の日経平均】 10,208 -233

  2002年01月14日(月)   TRegexp
「詳説 正規表現」は6章まで読みました。最後の7章はPerlでの正規表現についての詳しい説明ですが、とりあえずPerlはいいので一応読了ということにしておきます。 
 
正規表現だけで、Cのコメントのような入れ子を扱うのは面倒そうだなという感じです。.*のような表現が「貪欲な」という説明はわかりやすかったと思います。 
 
それとC++ BuilderにはPCRE以外にTRegexpという正規表現の扱いがあることがわかりました。これはTurbo C++の時代からあるようですが、何故かC++ Builder 5のHelpにも載っていません。情報はボーランドのサイトにありました。 
 
BREGEXP.DLLを試してみた簡単なプログラムの呼び出し部分だけを変えてTRegexpのテストをしてみました。 
 
TRegexpの特徴としては、機能は低いけれど、扱いは簡単です。 
 
使い方はまずをincludeしておき、正規表現の文字列を指定して、TRegexpのインスタンスをnewで作り、検索対象の文字列を指定してfindメソッドを呼ぶだけです。 
呼ぶ時にマッチした長さを返して欲しい場所(変数のアドレス)と検索開始位置(先頭からなら0)を教えます。 
findメソッドの戻り値は、マッチした部分の先頭位置が帰ってきます。マッチしなければ-1です。あとはその戻り値と返された長さを使えば、マッチした文字列を抜き出せます。 
戻り値に長さを足して次の検索開始位置を求めれば、繰り返しfindを掛けることで残りにまだマッチするものがあるかどうかもわかります。 
 
後始末はnewで作ったインスタンスをdeleteするだけです。 
 
{m,n}や ab|cd や大文字小文字の区別をしない、などはできませんが、内部で使うだけなら結構手軽で便利かもしれません。

  2002年01月13日(日)   正規表現
Helpファイルを見ていたら、C++ Builderの中でもPCRE (Perl Compatible Regular Expressions) というライブラリがあって、それを使えるみたいです。日本語が通るか調べていないのでわかりませんけれど。その他にもいくつか方法がありそうです。 
 
ということで「詳説 正規表現」というフクロウの表紙の本を買ってみました。まだ4章のはじめの方ですが、どうも昔からいろいろと変遷があるようです。 
 
本日の自転車の走行距離は35kmでした。10km以上走ったのは一ヶ月ぶりです。また今日も写真を撮っていないので、今年はまだ一枚も撮っていないことになります。

  2002年01月10日(木)   implib
このあいだ秀丸にセットしたBREGEXPという正規表現のDLLを、Delphiからは呼べるようなので、C++ Builderのプログラムからも呼べるかテストしてみました。C++ Builderを使うのは一年ぶりぐらいなのでけっこう手間取りました。 
 
■ *charをAnsiStringに入れる 
-------------------------------------------------------- 
AnsiStringを*charにするのにはc_str()というものがありますが、その逆は? というところでまずつまずきました。結局、変数であっても単純に=で代入するだけでOKでした。 
 
■ ライブラリの指定 
-------------------------------------------------------- 
「どのライブラリを使うか」と「それがどこにあるか」の二つを指定するのですが、それをどこで入力するのか迷いました。結局、「どのライブラリを使うか」は「プロジェクトに追加する」というかたちで、「それがどこにあるか」は「プロジェクトのオプション」のライブラリパスのダイアログでした。 
 
■ implib 
-------------------------------------------------------- 
BREGEXPで配布されているのはVC++のLIBなのでimplibで変換しなければなりません。でも単に implib xxx.lib BREGEXP.DLL だとexportされる関数名にアンダーバーがつかないので -a オプションをつけなければいけませんでした。 
 
その他BREGEXPのサポートページで説明されているものと、配布されている.hが少し異なるとか、検索パターン(正規表現)の文字列を/で囲むのを忘れるとか、少々手間取りましたが、とりあえず正規表現と対象文字列を入れてボタンを押すとマッチした部分が表示されるという簡単な作動確認はできました。 
 
【今日の日経平均】 10,538 -125