Boost Regex++

C++ で正規表現が使いたい。Boost Regex++ がよさげ。

boost入手・導入

http://www.boost.org/

boost_1_35_0.zip を入手。D:\boost_1_35_0 として解凍。
VCのインクルードパスに D:\boost_1_35_0 を追加。

regexビルド

boostの多くのモジュールはビルドしなくても使えるが、regexはビルドが必要。

Visual Studio 2005 Professional にて。
スタートメニューの [Visual Studio 2005] – [Visual Studio Tools] – [Visual Studio 2005 コマンド プロンプト] を実行。

> cd D:\boost_1_35_0\libs\regex\build
> nmake -f vc8.mak              (lib作成)
> nmake -f vc8.mak install      (VCディレクトリにlibをコピー)

参考:

http://d.hatena.ne.jp/twhs/20080112

コーディング実験

#include <boost/regex.hpp>
#include <string>
using namespace std;

void test()
{
	//簡単な検索 ("abcdefg" から "abc" の有無を判定)
	printf("-- simple --\n");
	{
		const char* source = "abcdefg"; //検索対象
		boost::reg_expression<char, boost::regex_traits<char> > regex("abc"); //正規表現
		boost::match_results<const char*> results; //結果
		//実行
		bool found = boost::regex_search(source, results, regex);
		printf("found = %d\n", found?1:0);
	}

	//抜き出し ("abcdafc" から "a.c" にマッチするものを検索)
	printf("-- pick up --\n");
	{
		const char* source = "abcdafc"; //検索対象
		boost::reg_expression<char, boost::regex_traits<char> > regex("a.c"); //正規表現
		boost::match_results<const char*> results; //結果
		//実行
		bool found = boost::regex_search(source, results, regex);
		if(found){
			string p = results.str(0);
			printf("found = %s\n", p.c_str());
		}
	}

	//カッコ (カッコ付きの正規表現。複数の結果を取得できる)
	printf("-- brackets --\n");
	{
		const char* source = "abcdafc"; //検索対象
		boost::reg_expression<char, boost::regex_traits<char> > regex("(a.c).*(.f)"); //正規表現
		boost::match_results<const char*> results; //結果
		//実行
		bool found = boost::regex_search(source, results, regex);
		if(found){
			for(int i=0;i<(int)results.size();i++){
				printf("found[%d]: pos = %d, len = %d, str = %s\n",
					i, results.position(i), results.length(i), results.str(i).c_str());
			}
		}
	}
}

参考:

http://www.s34.co.jp/cpptechdoc/article/regexpp/

実用に向けたコーディング

#include <boost/regex.hpp>
#include <string>
#include <vector>
using namespace std;
vector<string> get_match_strings(const char* _source, const char* _regex)
{
	const char* source = _source; //検索対象
	boost::reg_expression<char, boost::regex_traits<char> > regex(_regex); //正規表現
	boost::match_results<const char*> results; //結果
	//実行
	bool found = boost::regex_search(source, results, regex);
	//解釈
	vector<string> ret;
	if(found){
		for(int i=0;i<(int)results.size();i++){
			ret.push_back(results.str(i));
		}
	}
	return ret;
}

上のような関数を用意しておくと便利。ちょっと負荷はかかるけど。
で、下のように使う。

void test2()
{
	//文字列内から「URL全体」と「サーバ名」を抜き出し。 (正規表現は適当)
	vector<string> ret = get_match_strings(
		"abc http://www.google.co.jp/gonyo/ponyo/ def",
		"http://([A-Za-z\\.]+)/[A-Za-z\\./]+"
	);
	for(int i=0;i<(int)ret.size();i++){
		printf("match[%d] = %s\n", i, ret[i].c_str());
	}
}

落とし穴メモ

「#include <boost/regex.hpp>」と書くところを
「#include <boost/regex.h>」と書き間違えてしまった場合↓

error C2039: 'reg_expression' : 'boost' のメンバではありません。
error C2065: 'reg_expression' : 定義されていない識別子です。

ややこしやー。

Leave a comment

0 Comments.

Leave a Reply

( Ctrl + Enter )