C++ - Boost で正規表現置換!

Updated:


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

今回は正規表現でマッチした部分を置換する方法についてのの記録です。

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

0. 前提条件

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

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

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

File: 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
100
101
102
103
104
105
106
107
108
/*
 * Replacement of regular expressions by boost.
 */
#include <iostream>
#include <string>
#include <boost/regex.hpp>     // require "boost-regex-dev"

using namespace std;

/*
 * [CLASS] Process
 */
class Proc
{
    // Private Declaration
    string       sSrc;          // Source string
    string       sFmtA, sFmtS;  // Replace string (All, Sub)
    boost::regex reA, reS;      // Regular expression (All, Sub)
    string       result;        // Result
    bool regexReplaceA(string, boost::regex, string);  // All replace
    bool regexReplaceS(string, boost::regex, string);  // Sub replace

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

/*
 * Proc - Constructor
 */
Proc::Proc()
{
    // Initial settings
    sSrc  = "RedHatEnterpriseリナックス CentOS サイエンティフィックLinux Fedora VineLinux";
    reA   = "Linux";                   // All matching - Regular expression
    sFmtA = "リナックス";              // All matching - Replace string
    reS   = "([^ ]+)(Linux)";          // Sub matching - Regular expression
    sFmtS = "(?1****)(?2リナックス)";  // Sub matching - Replace string
}

/*
 * Main Process
 */
bool Proc::execMain()
{
    try {
        // Replace (All match)
        if (!regexReplaceA(sSrc, reA, sFmtA)) return false;

        // Replace (Sub match)
        if (!regexReplaceS(sSrc, reS, sFmtS)) return false;
    } catch (char *e) {
        cerr << "[EXCEPTION] " << e << endl;
        return false;
    }
    return true;
}

// Replace (All match)
bool Proc::regexReplaceA(string sSrc, boost::regex re, string sFmt)
{
    try {
        cout << "[Source string]\n  " << sSrc << "\n"
             << "[Replace]\n  " << re << " -> "
             << sFmt << endl;
        result = boost::regex_replace(sSrc, re, sFmt);
        cout << "[Result]\n  " << result << endl;
    } catch (char *e) {
        cerr << "[EXCEPTION] " << e << endl;
        return false;
    }
    cout << endl;
    return true;
}

// Replace (Sub match)
bool Proc::regexReplaceS(string sSrc, boost::regex re, string sFmt)
{
    try {
        cout << "[Source string]\n  " << sSrc << "\n"
             << "[Replace]\n  " << re << " -> "
             << sFmt << endl;
        result = boost::regex_replace(
            sSrc, re, sFmt, boost::match_default | boost::format_all
        );
        cout << "[Result]\n  " << result << endl;
    } 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 ライブラリを読み込むオプション)

$ g++ -Wall -O2 -o BoostRegexR BoostRegexR.cpp -lboost_regex

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

3. 実行

実際に、実行してみる。

 ./BoostRegexR
[Source string]
  RedHatEnterpriseリナックス CentOS サイエンティフィックLinux Fedora VineLinux
[Replace]
  Linux -> リナックス
[Result]
  RedHatEnterpriseリナックス CentOS サイエンティフィックリナックス Fedora Vineリナックス

[Source string]
  RedHatEnterpriseリナックス CentOS サイエンティフィックLinux Fedora VineLinux
[Replace]
  ([^ ]+)(Linux) -> (?1****)(?2リナックス)
[Result]
  RedHatEnterpriseリナックス CentOS ****リナックス Fedora ****リナックス

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

以上。





 

Sponsored Link

 

Comments