C++と正規表現(regex++) テストその2 †C/C++言語ソースファイルを想定し、正規表現を使って解析する。 制約 †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からの分も含む) †boost、regexライブラリのビルドに成功。 課題 †インクルードファイル名が"xxxx.h.h"のように、複数のピリオドを含んでいたら?(打開) #define CHAR_THREE '3' // ソースとしては問題のない書き方 今はcoutで画面表示に成功しているが、UNICODE対応(wsmatch使用)にすると、コンパイルエラーとなる。(打開) string( partial[0].first, partial[0].second).c_str() ) // マッチ開始ポイントと終了ポイントを利用してstring型を作れる。 |