SSブログ

C++で正規表現(vbscript.dll編) [プログラミング]

C++で正規表現を使います(その2)。

Windowsでは、VBScript用の正規表現を他のプログラムから利用できるようになっています。COMテクノロジを使うことで。

そのためには、いくつかの手順が必要です。

Visual Studio 付属のOLE Viewerで探すと、「Microsoft VBScript Regular Expressions」が見つかり、vbscript.dllで提供されていることが分かります。

正規表現タイプライブラリ

そこで、以下の様にプログラムを書いてみます。

#import "vbscript.dll"

すると、正規表現を使うためのクラスが使用可能に………なりません。

何故に?
MSDNによれば、olb、tlb、dll が指定できると書いてあるのに……。
XMLは「#import "msxml.dll"」で使えるようになるのに……。

そこで、あらためてOLE Viewerの画面を良く見てみると、ファイル名が「vbscript.dll\3」となっています。
そんなファイルはもちろん存在せず、「#import "vbscript.dll\3"」としてもエラーになります。

さて、#importディレクティブは、タイプライブラリを指定するものなのですが、どういう理屈でDLLを指定できるのかと言うと……
DLLのリソースにタイプライブラリの情報を持っていて、そのリソースを参照しているのです。

では、vbscript.dllではどうなっているのでしょう。

vbscript.dllのリソース

タイプライブラリのリソースが3つあります。
この3つ目が正規表現用のタイプライブラリなのですが(2つ目は古いバージョンの正規表現のタイプライブラリ情報)、#importディレクティブでは1つ目のものしか参照できないのです。


さて、能書きはココまでとして、実際にどうしたら正規表現を使えるようになるかの手順を書きます。

  1. OLE Viewerで「Microsoft VBScript Regular Expressions 5.5」をダブルクリックする。
  2. メニューから[File]-[Save As]を選択する。ファイル名を(例えば)"vbscript.idl"で保存する。
  3. コマンドプロンプトで midl vbscript.IDLと入力する。
  4. "vbscript.tbl"が出来上がる。
  5. ソースコードに「#import "vbscript.tlb"」と記述する。

これで、正規表現用のクラスが使えるようになります。
(何故かウチの環境ではIDLファイルの保存に失敗しましたが)

(いつからこの形式が使えるようになったのか分かりませんが)#importディレクティブにGUIDを指定出来るようになっているので、上の手順を踏むのが面倒な人は、次の書き方でもOKです。

#import "libid:3F4DACA7-160D-11D2-A8E9-00104B365C9F" version("5.5")

ココまでが前置きです。これで漸くコード本体に入れます。

::CoInitialize(NULL);
{
    VBScript_RegExp_55::IRegExp2Ptr ex(__uuidof(VBScript_RegExp_55::RegExp));
    ex->PutPattern(pattern);

    VBScript_RegExp_55::IMatchCollection2Ptr result_list = ex->Execute(target);

    for (long i = 0; i < result_list->GetCount(); i++) {

        VBScript_RegExp_55::IMatch2Ptr result = result_list->GetItem(i);
        std::cout << "pos = " << result->GetFirstIndex() << "\n"
                  << "len = " << result->GetLength() << "\n"
                  << "str = " << static_cast<const char*>(result->GetValue()) << "\n";

        VBScript_RegExp_55::ISubMatchesPtr sub = result->GetSubMatches();
        for (long j = 0; j < sub->GetCount(); j++) {
            std::cout << "sub = "
                      << static_cast<const char*>(static_cast<_bstr_t>(sub->GetItem(j)))
                      << "\n";
        }
    }
}    
::CoUninitialize();

COMテクノロジを使うので、CoInitialize(), CoUninitialize()が必要です。

Executeは、パターンにマッチする部分を検索します。
文字列中のマッチする箇所を全て検索してしまうので、長い文字列から検索すると時間がかかるかも知れません。

他に、一致判定(Test)と、置換(Replace)があります。

日本語にも対応しています。

[飛行機] 今日の一冊
5分でたのしむ数学50話

5分でたのしむ数学50話

  • 作者: エアハルト ベーレンツ
  • 出版社/メーカー: 岩波書店
  • 発売日: 2007/12
  • メディア: 単行本

タグ:Windows VisualC++
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

C++で正規表現(boost::rege..昔語り ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。