''[[FrontPage]]''
* C++と正規表現(regex++) テストその2 [#j066e05d]
C/C++言語ソースファイルを想定し、正規表現を使って解析する。~
[[C++入門/正規表現1]]~
[[C++入門/正規表現3]]
** 制約 [#x3955e7b]
MFC、.NET関数を使用しないこと。~
~
#include <string> //
#include <iostream> // for cout
#include <boost/regex.hpp> // for regex++
#include <tchar.h> //
// # include "x.x.h" // (空)宣言文のあらゆる可能性をテスト
//
using namespace std; // 名前空間
using namespace boost; // 名前空間
//
#ifdef UNICODE // 強引に対応。単独プロジェクトならOK?
typedef wregex tregex; // ま、正直どうやったら良いのか分からない。
typedef wstring tstring; //
typedef wsmatch tsmatch; //
//typedef wprintf tprintf; // * 出力に関しては自分で統一すべきか
#else //
typedef regex tregex; //
typedef string tstring; //
typedef smatch tsmatch; //
//typedef wprintf tprintf; // * 出力に関しては自分で統一すべきか
#endif //
//
tregex targetI( // 正規表現のコンパイル
_T("#[[:space:]]*(include)") // "#"と空白を挟んだ"include"
_T("[[:space:]]*L*\"") // 0以上の空白文字に続く'"'
_T("(.*?") // ファイル名を最短マッチ
_T("\.[hc]p{0,2})") // 想定される拡張子
_T("\"" )); // ダブルクォーテーション右
//
char main( void ) // 正規表現のテスト(インクルード宣言を探す)
{ //
const tstring file( // ソースファイルの内容を仮定
_T("#include <windows.h> \n") //
_T("#include \"me.h.h\" \n") //
_T("#include \"stuff.cpp\"")); //
//
tstring::const_iterator start; // イテレータの宣言
tstring::const_iterator end; // イテレータの宣言
//
start = file.begin(); // 開始イテレータの設定
end = file.end(); // 末尾イテレータの設定
//
tsmatch partial; // マッチ情報を格納する
match_flag_type flags = match_default; // flagの初期設定
//
while(regex_search(start, end, partial, targetI, flags)) // ループ
{ // マッチが見つかった場合
printf( "partial[0] = %s\n", // 画面表示(マルチバイト)
string( partial[0].first, partial[0].second).c_str() ); // 部分文字列[0](全体)
wprintf( L"partial[1] = %s\n", // 画面表示(ワイド文字列)
wstring( partial[1].first, partial[1].second).c_str() ); // 部分文字列[1]
wprintf( L"partial[2] = %s\n", // 画面表示(ワイド文字列)
wstring( partial[2].first, partial[2].second).c_str() ); // 部分文字列[2]
wprintf( L"partial[3] = %s\n", // 画面表示(ワイド文字列)
wstring( partial[3].first, partial[3].second).c_str() ); // 部分文字列[3]
wprintf( L"partial[4] = %s\n\n", // 画面表示(ワイド文字列)
wstring( partial[4].first, partial[4].second).c_str() ); // 部分文字列[4]
//
start = partial[0].second; // 開始イテレータの更新(次のマッチを探す)
//
flags |= match_prev_avail; // flagの更新
flags |= match_not_bob; //
} //
//
getchar(); // 表示結果確認用
return 0; //
}
表示結果
partial[0] = #include "me.h.h"
partial[1] = include
partial[2] = me.h.h
partial[3] =
partial[4] =
partial[0] = #include "stuff.cpp"
partial[1] = include
partial[2] = stuff.cpp
partial[3] =
partial[4] =
*** 修正履歴 (その1からの分も含む) [#o388b8f2]
boost、regexライブラリのビルドに成功。~
Unicodeへの対応は強引だが可能?(なにがおもしろいのかがいまいち分からないが)
*** 課題 [#ze539c80]
インクルードファイル名が"xxxx.h.h"のように、複数のピリオドを含んでいたら?(打開)~
defineによる定数定義が、文字定数によって行われていたら?(打開可能)
#define CHAR_THREE '3' // ソースとしては問題のない書き方
今はcoutで画面表示に成功しているが、UNICODE対応(wsmatch使用)にすると、コンパイルエラーとなる。(打開)~
むしろ、sub_matchが文字列として表示されていることが奇跡的?(打開)~
string( partial[0].first, partial[0].second).c_str() ) // マッチ開始ポイントと終了ポイントを利用してstring型を作れる。