mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

C++ - Boost で正規表現マッチング(Iterator 版)!

[ プログラミング ] [ C言語, 正規表現 ]

こんばんは。

前回 C++ で Boost(Regex) ライブラリを利用して正規表現マッチングを行う方法について紹介しました。

今回はイテレータを使用したバージョンについての記録です。

(C++ にそれほど精通している訳でもありません。ご承知おきください)

0. 前提条件

  • Linux Mint 17 での作業を想定。
  • g++(c++) のバージョンは 4.8.2
  • boost-regex-dev パッケージ導入済み。(apt-get 等で)

1. C++ ソースコード作成

以下のようにソースコードを作成した。

BoostRegexI.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * Matching regular expressions using iterators by boost.
 */
#include <iostream>
#include <string>
#include <boost/regex.hpp>     // require "boost-regex-dev"

using namespace std;

/*
 * [CLASS] Process
 */
class Proc
{
    // Private Declaration
    string       sSrcC, sPtnC;                 // Source string, Regex pattern (char)
    string       sSrcW, sPtnW;                 // Source string, Regex pattern (wchar)
    boost::regex reC, reW;                     // Regular expression
    bool regexIterator(string, boost::regex);  // Iterator matching

public:
    Proc();           // Constructor
    bool execMain();  // Main Process
};

/*
 * Proc - Constructor
 */
Proc::Proc()
{
    // Initial settings
    sSrcC = "RedHatEnterpriseLinux CentOS ScientificLinux Fedora VineLinux";
    sSrcW = "レッドハットリナックス セントオーエス サイエンティフィックリナックス ヴァインリナックス";
    reC   = "([^ ]+)Linux";
    reW   = "([^ ]+)リナックス";
}

/*
 * Main Process
 */
bool Proc::execMain()
{
    try {
        // Iterator matching (char)
        if (!regexIterator(sSrcC, reC)) return false;

        // Iterator matching (wchar)
        if (!regexIterator(sSrcW, reW)) return false;
    } catch (char *e) {
        cerr << "[EXCEPTION] " << e << endl;
        return false;
    }
    return true;
}

// Iterator matching
bool Proc::regexIterator(string sSrc, boost::regex re)
{
    try {
        cout << "[Source string] " << sSrc << "\n"
             << "[Regex pattern] " << re   << endl;
        boost::sregex_iterator iter(sSrc.begin(), sSrc.end(), re);
        boost::sregex_iterator last;
        if (iter->size() == 0) {
            cout << "[ Unmatched ]" << endl;
        } else {
            cout << "[ Matched ]" << endl;
            while (iter != last) {
                for (size_t i = 0; i < iter->size(); ++i) {
                    cout << i << ':' << iter->position(i) << ','
                         << iter->length(i) << ':'
                         << iter->str(i) << ' ';
                }
                cout << endl;
                ++iter;
            }
        }
    } catch (char *e) {
        cerr << "[EXCEPTION] " << e << endl;
        return false;
    }
    cout << endl;
    return true;
}

/*
 * Execution
 */
int main(){
    try {
        Proc objMain;
        bool bRet = objMain.execMain();
        if (!bRet) cout << "ERROR!" << endl;
    } catch (char *e) {
        cerr << "[EXCEPTION] " << e << endl;
        return 1;
    }
    return 0;
}

2. C++ ソースコンパイル

以下のコマンドで C++ ソースをコンパイルする。
-Wall 警告も出力するオプション、-O2 最適化のオプション、-lboost_regex boost_regex ライブラリを読み込むオプション)

1
$ g++ -Wall -O2 -o BoostRegexI BoostRegexI.cpp -lboost_regex

何も出力されなければ成功。

3. 実行

実際に、実行してみる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ ./BoostRegexI
[Source string] RedHatEnterpriseLinux CentOS ScientificLinux Fedora VineLinux
[Regex pattern] ([^ ]+)Linux
[ Matched ]
0:0,21:RedHatEnterpriseLinux 1:0,16:RedHatEnterprise
0:29,15:ScientificLinux 1:29,10:Scientific
0:52,9:VineLinux 1:52,4:Vine

[Source string] レッドハットリナックス セントオーエス サイエンティフィックリナックス ヴァインリナックス
[Regex pattern] ([^ ]+)リナックス
[ Matched ]
0:0,33:レッドハットリナックス 1:0,18:レッドハット
0:56,45:サイエンティフィックリナックス 1:56,30:サイエンティフィック
0:102,27:ヴァインリナックス 1:102,12:ヴァイン

当方の場合、正規表現マッチングは意外と頻繁に使用するので、後学のために記録しておいた次第です。

以上。

Comments