正規表現(Regular Expressions、略称:regex)は、文字列のパターンマッチングや検索に広く利用される技術です。C++では、正規表現を使用するために、標準ライブラリに
ヘッダが提供されており、これを利用することで効率的な文字列操作が可能になります。本記事では、C++における正規表現の基本から応用までを完全かつ包括的に解説します。
正規表現とは?
正規表現は、特定のパターンに一致する文字列を検索したり、置き換えたりするための表現方法です。例えば、特定の形式の日付(YYYY-MM-DD)やメールアドレスなど、規則的なパターンを持つ文字列を扱う際に便利です。

C++における正規表現の基本
C++では、
ライブラリを使用して正規表現を利用します。このライブラリには、正規表現を扱うためのクラスや関数が豊富に揃っています。基本的な使い方を見ていきましょう。
1. ヘッダファイルのインクルード
まず、正規表現を利用するために
ヘッダをインクルードします。
cpp#include
#include
#include
2. 正規表現オブジェクトの作成
std::regex
クラスを使って、正規表現のパターンを定義します。
cppstd::regex pattern("[0-9]+"); // 数字が1回以上続くパターン
この例では、1回以上の数字にマッチする正規表現パターンを定義しています。
3. 文字列のマッチング
std::regex_match
関数を使って、文字列全体がパターンに一致するかを確認します。
cppstd::string text = "12345";
if (std::regex_match(text, pattern)) {
std::cout << "一致しました!" << std::endl;
} else {
std::cout << "一致しませんでした。" << std::endl;
}
このコードは、文字列"12345"
が正規表現"[0-9]+"
に一致するかをチェックし、一致すればメッセージを表示します。
4. 部分一致の検索
std::regex_search
を使用すると、文字列内でパターンに一致する部分があるかを検索できます。
cppstd::string text = "abc123xyz";
if (std::regex_search(text, pattern)) {
std::cout << "数字が含まれています!" << std::endl;
} else {
std::cout << "数字は含まれていません。" << std::endl;
}
このコードは、文字列"abc123xyz"
の中に数字が含まれているかを調べます。
5. 文字列の置換
std::regex_replace
を使うことで、正規表現に一致した部分を別の文字列に置き換えることができます。
cppstd::string text = "abc123xyz";
std::string replaced = std::regex_replace(text, pattern, "数字");
std::cout << replaced << std::endl; // abc数字xyz
このコードでは、文字列中の数字部分が"数字"
に置き換えられます。
正規表現のパターン構文
C++の正規表現パターンでは、特定の記号や構文を使用して、より複雑なパターンを表現できます。ここでは、よく使われる構文を紹介します。
1. メタ文字
メタ文字は、正規表現パターンの中で特別な意味を持つ文字です。以下は、主なメタ文字とその意味です。
-
.
:任意の1文字に一致 -
^
:文字列の先頭に一致 -
$
:文字列の末尾に一致 -
*
:直前の文字が0回以上繰り返される -
+
:直前の文字が1回以上繰り返される -
?
:直前の文字が0回または1回現れる -
{n,m}
:直前の文字がn回以上、m回以下繰り返される
2. 文字クラス
文字クラスは、特定の文字の集合を表します。
-
[abc]
:a、b、cのいずれか1文字に一致 -
[^abc]
:a、b、c以外の任意の1文字に一致 -
[0-9]
:任意の数字1文字に一致 -
[a-z]
:任意の小文字アルファベット1文字に一致 -
\d
:任意の数字([0-9]
と同等) -
\w
:単語文字(アルファベット、数字、アンダースコア)
3. グループ化とキャプチャ
()
を使って、パターンの一部をグループ化し、その部分にマッチした内容をキャプチャすることができます。
cppstd::regex pattern("(\\d+)-(\\d+)");
std::string text = "123-456";
std::smatch match;
if (std::regex_match(text, match, pattern)) {
std::cout << "最初の数字: " << match[1] << std::endl; // 123
std::cout << "次の数字: " << match[2] << std::endl; // 456
}
この例では、"123-456"
の文字列から、123
と456
の部分をキャプチャしています。
高度な正規表現の使用
C++では、正規表現をさらに効果的に活用するために、以下のような高度な操作も可能です。
1. 正規表現のフラグ
std::regex
には、検索時に動作を変更するためのフラグがあります。例えば、大小文字を区別しない検索や、複数行を考慮した検索などができます。
-
std::regex::icase
:大小文字を区別しない検索 -
std::regex::multiline
:複数行の検索をサポート
cppstd::regex pattern("abc", std::regex::icase);
2. 正規表現のイテレータを使用した検索
C++11以降、std::sregex_iterator
を使って、文字列中のすべての一致部分を反復処理できます。
cppstd::string text = "abc123def456ghi";
std::regex pattern("\\d+");
for (std::sregex_iterator i(text.begin(), text.end(), pattern), end; i != end; ++i) {
std::cout << "一致した数字: " << i->str() << std::endl;
}
このコードは、文字列中のすべての数字を列挙します。
結論
C++における正規表現は、非常に強力で柔軟なツールです。
ライブラリを使うことで、文字列の検索、置換、検証など、さまざまな操作を簡単に実行できます。正規表現を理解し、活用することで、効率的かつ高機能な文字列処理が可能になります。