''[[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型を作れる。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS