VB에서 RegExp 객체를 참조하고 사용하면 굉장히 편안하게 사용할 수 있지만..
이게 COM인 관계로 C++에서는 이를 사용하기 위해 많은 삽질을 해야한다.. (아 COM 싫다)
삽질의 순서는 다음과 같다:
1. Visual Studio 6.0에 포함되어 있는 OLE View를 실행한다.
2. 왼쪽의 Object Classes아래 Type Libraries 중 "Microsoft VBScript Regular Expressions 5.5" 를 선택한다.
3. 새 창이 나오는데 오른쪽에 나오는 내용이 .IDL 파일의 내용이다. 이 내용을 클립보드로 복사한다. 현재 우리집 컴퓨터에서는 아래와 같이 나온다:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: 3
[
uuid(3F4DACA7-160D-11D2-A8E9-00104B365C9F),
version(5.5),
helpstring("Microsoft VBScript Regular Expressions 5.5")
]
library VBScript_RegExp_55
{
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("STDOLE2.TLB");
// Forward declare all types defined in this typelib
interface IRegExp;
interface IMatch;
interface IMatchCollection;
interface IRegExp2;
interface IMatch2;
interface IMatchCollection2;
interface ISubMatches;
[
odl,
uuid(3F4DACA0-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface IRegExp : IDispatch {
[id(0x00002711), propget]
HRESULT Pattern([out, retval] BSTR* pPattern);
[id(0x00002711), propput]
HRESULT Pattern([in] BSTR pPattern);
[id(0x00002712), propget]
HRESULT IgnoreCase([out, retval] VARIANT_BOOL* pIgnoreCase);
[id(0x00002712), propput]
HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
[id(0x00002713), propget]
HRESULT Global([out, retval] VARIANT_BOOL* pGlobal);
[id(0x00002713), propput]
HRESULT Global([in] VARIANT_BOOL pGlobal);
[id(0x00002714)]
HRESULT Execute(
[in] BSTR sourceString,
[out, retval] IDispatch** ppMatches);
[id(0x00002715)]
HRESULT Test(
[in] BSTR sourceString,
[out, retval] VARIANT_BOOL* pMatch);
[id(0x00002716)]
HRESULT Replace(
[in] BSTR sourceString,
[in] BSTR replaceString,
[out, retval] BSTR* pDestString);
};
[
odl,
uuid(3F4DACA1-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface IMatch : IDispatch {
[id(00000000), propget]
HRESULT Value([out, retval] BSTR* pValue);
[id(0x00002711), propget]
HRESULT FirstIndex([out, retval] long* pFirstIndex);
[id(0x00002712), propget]
HRESULT Length([out, retval] long* pLength);
};
[
odl,
uuid(3F4DACA2-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface IMatchCollection : IDispatch {
[id(0x00002711), propget]
HRESULT Item(
[in] long index,
[out, retval] IDispatch** ppMatch);
[id(0x00000001), propget]
HRESULT Count([out, retval] long* pCount);
[id(0xfffffffc), propget]
HRESULT _NewEnum([out, retval] IUnknown** ppEnum);
};
[
odl,
uuid(3F4DACB0-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface IRegExp2 : IDispatch {
[id(0x00002711), propget]
HRESULT Pattern([out, retval] BSTR* pPattern);
[id(0x00002711), propput]
HRESULT Pattern([in] BSTR pPattern);
[id(0x00002712), propget]
HRESULT IgnoreCase([out, retval] VARIANT_BOOL* pIgnoreCase);
[id(0x00002712), propput]
HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
[id(0x00002713), propget]
HRESULT Global([out, retval] VARIANT_BOOL* pGlobal);
[id(0x00002713), propput]
HRESULT Global([in] VARIANT_BOOL pGlobal);
[id(0x00002717), propget]
HRESULT Multiline([out, retval] VARIANT_BOOL* pMultiline);
[id(0x00002717), propput]
HRESULT Multiline([in] VARIANT_BOOL pMultiline);
[id(0x00002714)]
HRESULT Execute(
[in] BSTR sourceString,
[out, retval] IDispatch** ppMatches);
[id(0x00002715)]
HRESULT Test(
[in] BSTR sourceString,
[out, retval] VARIANT_BOOL* pMatch);
[id(0x00002716)]
HRESULT Replace(
[in] BSTR sourceString,
[in] VARIANT replaceVar,
[out, retval] BSTR* pDestString);
};
[
odl,
uuid(3F4DACB1-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface IMatch2 : IDispatch {
[id(00000000), propget]
HRESULT Value([out, retval] BSTR* pValue);
[id(0x00002711), propget]
HRESULT FirstIndex([out, retval] long* pFirstIndex);
[id(0x00002712), propget]
HRESULT Length([out, retval] long* pLength);
[id(0x00002713), propget]
HRESULT SubMatches([out, retval] IDispatch** ppSubMatches);
};
[
odl,
uuid(3F4DACB2-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface IMatchCollection2 : IDispatch {
[id(00000000), propget]
HRESULT Item(
[in] long index,
[out, retval] IDispatch** ppMatch);
[id(0x00000001), propget]
HRESULT Count([out, retval] long* pCount);
[id(0xfffffffc), propget]
HRESULT _NewEnum([out, retval] IUnknown** ppEnum);
};
[
odl,
uuid(3F4DACB3-160D-11D2-A8E9-00104B365C9F),
hidden,
dual,
nonextensible,
oleautomation
]
interface ISubMatches : IDispatch {
[id(00000000), propget]
HRESULT Item(
[in] long index,
[out, retval] VARIANT* pSubMatch);
[id(0x00000001), propget]
HRESULT Count([out, retval] long* pCount);
[id(0xfffffffc), propget]
HRESULT _NewEnum([out, retval] IUnknown** ppEnum);
};
[
uuid(3F4DACA4-160D-11D2-A8E9-00104B365C9F)
]
coclass RegExp {
[default] interface IRegExp2;
};
[
uuid(3F4DACA5-160D-11D2-A8E9-00104B365C9F),
noncreatable
]
coclass Match {
[default] interface IMatch2;
};
[
uuid(3F4DACA6-160D-11D2-A8E9-00104B365C9F),
noncreatable
]
coclass MatchCollection {
[default] interface IMatchCollection2;
};
[
uuid(3F4DACC0-160D-11D2-A8E9-00104B365C9F),
noncreatable
]
coclass SubMatches {
[default] interface ISubMatches;
};
};4. 원하는 idl파일로 저장한다. 여기서는 vbscript.idl로 저장하였다.
5. midl을 실행한다. midl은 "Visual Studio 2005 명령 프롬프트"와 같은 곳에서 실행하면 편하다.
6. 아래와 같이 실행한다:
midl vbscript.idl /h vbscript.h
7. 그러면 vbscript.tbl 파일이 생성된다.
8. 이제 이 파일을 이용하여 코딩한다.
코드 예제는 다음과 같다. 대강 짠 소스라 개판이다.
try
{
LPCTSTR lpszPattern = _T("\\d{3}-\\d{3}-\\d{4}");
LPCTSTR pStr = _T("011-123-1234");
HRESULT hr;
hr = CoInitialize(0);
if(SUCCEEDED(hr))
{
{
IRegExpPtr regExp( __uuidof(RegExp) );
regExp->Pattern = _bstr_t(lpszPattern);
if ( regExp->Test(pStr) )
{
IMatchCollectionPtr matches=regExp->Execute(pStr);
printf("%d\n", matches->Count);
if ( matches->Count== 1)
{
IMatchPtr match = matches->Item[0];
BSTR pp;
match->get_Value(&pp);
_tprintf(_T("OK. Value: %s\n"), pp);
}
}
else
{
printf("NO\n");
}
}
CoUninitialize();
}
}
catch (_com_error& e)
{
AfxMessageBox( e.ErrorMessage() );
}
더 쉬운방법이 있으려나? 알면 좋겠지만... 잘 모르겠다. 그냥 사용하기 빡세다. 조만간 wrapping class좀 만들어야겠다.



Attribution/Share Alike 2.0 license






