RealPath:
WebPath:
2017/02/12 02:24 (JST) 更新
Boost >>

正規表現機能の利用

Contents

前提

Boost のいくつかの機能は Boost のビルドをしなくてもそのまま使えるが、今回扱う正規表現機能 boost::regex については Boost ビルドが必要なのであらかじめビルドしておくこと。

簡単な検索

C++コード
#include <stdio.h>
#include <string>
#include <boost/regex.hpp>

int main()
{
    // 簡単な検索 ("abcdefg" から "cd." の有無を判定)
    const char* source = "abcdefg"; // 検索対象
    boost::reg_expression<char, boost::regex_traits<char> > regex("cd."); // 正規表現

    // 検索実行
    boost::match_results<const char*> results; // 結果格納用
    bool found = boost::regex_search(source, results, regex);

    // 結果表示
    printf("found = %d\n", found ? 1 : 0);
    if (found) {
        printf("position = %ld\n", results.position());
    }
}
実行結果
found = 1
position = 2

抽出

C++コード
#include <stdio.h>
#include <string>
#include <boost/regex.hpp>

int main()
{
    // 抜き出し ("abcdafc" から "a.c" にマッチするものを探して抽出)
    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) {
        std::string p = results.str(0);
        printf("found string = %s\n", p.c_str());
    }
}
実行結果
found string = abc

カッコ付きの正規表現による抽出

C++コード
#include <stdio.h>
#include <string>
#include <boost/regex.hpp>

int main()
{
    // 検索対象
    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());
        }
    }
}
実行結果
found[0]: pos = 0, len = 6, str = abcdaf
found[1]: pos = 0, len = 3, str = abc
found[2]: pos = 4, len = 2, str = af

実用に向けたラップ関数

util.cpp
#include <stdio.h>
#include <string>
#include <vector>
#include <boost/regex.hpp>

std::vector<std::string> get_match_strings(
    const char* source, // 検索対象
    const char* regex   // 正規表現
)
{
    // 正規表現インスタンス
    boost::reg_expression<char, boost::regex_traits<char> > regexObj(regex);

    // 検索実行
    boost::match_results<const char*> results; // 結果格納用
    bool found = boost::regex_search(source, results, regexObj);

    // 検索成功した場合はマッチ部の内容を ret に詰めて返す
    std::vector<std::string> ret;
    if (found) {
        for (int i = 0; i<(int)results.size(); i++) {
            ret.push_back(results.str(i));
        }
    }
    return ret;
}

上のようなユーティリティ関数を用意しておくと便利。ちょっと負荷はかかるけど。

この get_match_strings() は以下のように使う。

main.cpp
#include <stdio.h>
#include <string>
#include <vector>

int main()
{
    // 文字列内から「URL全体」と「サーバ名」を抜き出し (正規表現は適当)
    std::vector<std::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());
    }
}
出力結果
match[0] = http://www.google.co.jp/gonyo/ponyo/
match[1] = www.google.co.jp

落とし穴メモ

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

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

参考