トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

Microsoft Visual C++ 6、正規表現を使う

[カテゴリ:言語]
[カテゴリ:VC6]

正規表現を使う(20070918)

フリーのライブラリを使うという選択肢もありますが、
VBScriptのRegExpを使うのが簡単そうなのでやってみた。
といってもVCからCOMを呼ぶだけですが、実はVCからCOM呼ぶのは
初めてだったりする。

Clinick's Clinic on Scripting: 正規表現による Visual Basic Scripting Edition (VBScript) の機能強化:
http://www.microsoft.com/japan/msdn/columns/scripting/scripting051099.aspx

vbscript.IDLを得る

OLE View(oleview.exe)起動
「Object Classes → Type Libraries → Microsoft VBScript Regular Expressions (Ver 1.0)」右クリックメニューから「View」クリック
ITypeInfo Viewer 起動
「File → Save As」でvbscript.IDLで保存

vbscript.tlbを得る

C:\>"C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
Setting environment for using Microsoft Visual C++ tools.
C:\>
C:\>midl
Microsoft (R) MIDL Compiler Version 5.01.0164
Copyright (c) Microsoft Corp 1991-1997. All rights reserved.
midl : command line error MIDL1000 : missing source-file name

C:\>MIDL vbscript.IDL /h vbscript.h
Microsoft (R) MIDL Compiler Version 5.01.0164
Copyright (c) Microsoft Corp 1991-1997. All rights reserved.
Processing .\vbscript.IDL
vbscript.IDL
Processing C:\PROGRA~1\MICROS~2\VC98\INCLUDE\oaidl.idl
oaidl.idl
Processing C:\PROGRA~1\MICROS~2\VC98\INCLUDE\objidl.idl
objidl.idl
Processing C:\PROGRA~1\MICROS~2\VC98\INCLUDE\unknwn.idl
unknwn.idl
Processing C:\PROGRA~1\MICROS~2\VC98\INCLUDE\wtypes.idl
wtypes.idl

C:\>
C:\>dir vbscript.*
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 7834-4EF9 です

 C:\ のディレクトリ

2007/08/22  21:52               25,638 vbscript.h
2007/08/22  21:47                3,266 vbscript.IDL
2007/08/22  21:52                3,624 vbscript.tlb
               3 個のファイル              32,528 バイト
               0 個のディレクトリ     174,616,576 バイトの空き領域

C:\>

サンプルソース

サンプルで使ったのは以下。

  • プロパティ
    • RegExp.Pattern
    • RegExp.IgnoreCase
    • RegExp.Global
  • メソッド
    • RegExp.Test()
using namespace std;

#include <windows.h>
#include <cstdio>
#import "vbscript.tlb" no_namespace named_guids 

void test(IRegExpPtr reg_exp, const CString& pattern, const CString &source)
{
  reg_exp->PutGlobal(VARIANT_TRUE);
  reg_exp->PutIgnoreCase(VARIANT_TRUE);
  reg_exp->PutPattern((LPCTSTR)pattern);
  {
    cout << "pattern:" << (LPCTSTR)pattern << " ";
    cout << "source:" << (LPCTSTR)source << "\n";
    VARIANT_BOOL ret = reg_exp->Test((LPCTSTR)source);
    if (ret != VARIANT_TRUE) {
      cout << "一致しませんでした。\n";
    } else {
      cout << "一致しました。\n";
    }
  }
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  int nRetCode = 0;

  // MFC の初期化および初期化失敗時のエラーの出力
  if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  {
    // TODO: 必要に応じてエラー コードを変更してください。
    cerr << _T("Fatal Error: MFC initialization failed") << endl;
    nRetCode = 1;
  }
  else
  {

    HRESULT hr = ::CoInitialize(NULL);
    if (SUCCEEDED(hr)) {

      // インスタンス生成
      IRegExpPtr reg_exp = NULL;
      HRESULT hr = reg_exp.CreateInstance(CLSID_RegExp);
      if (FAILED(hr)) {
        cerr << "err!! RegExp CreateInstance";
        nRetCode = 1;
      }

      if (nRetCode == 0) {
        try {
          test(reg_exp, "^[0-9]*$", "123");
          test(reg_exp, "^[0-9]*$", "abc");
        }
        catch (_com_error* e) {
          cerr << "com err!! " << e->Error();
        }

        // インスタンス開放
        reg_exp.Release();
      }
    }

    ::CoUninitialize();
  }

  return nRetCode;
}

サンプル実行結果

pattern:^[0-9]*$ source:123
一致しました。
pattern:^[0-9]*$ source:abc
一致しませんでした。

最終更新時間:2007年09月18日 18時49分10秒