はじめに
C++で、ユーザーが入力した文字列が「メールアドレスの形式に合っているか」「YYYY-MM-DD
という日付の形式になっているか」といった、特定のフォーマット検証を行いたい場合があります。
C++11で導入された**<regex>
ライブラリのstd::regex_match
関数は、このような「文字列全体がパターンに完全一致するか」という検証に最適です。さらに、正規表現のキャプチャグループ**機能と組み合わせることで、マッチした部分文字列(年、月、日など)を個別に抽出することもできます。
【前提】C++11とは?
C++11は、2011年に正式化されたC++言語のメジャーアップデート版です。<regex>
ライブラリはこのC++11で導入されたため、利用するにはC++11以降に対応したコンパイラが必要です。
regex_match
を使ったサンプルコード
このコードは、電話番号の文字列が「XXX-XXXX-XXXX
」というパターンに一致するかを検証し、一致した場合は市外局番、市内局番、加入者番号を個別に抽出して表示します。
完成コード
#include <iostream>
#include <string>
#include <regex> // regex, regex_match, smatch
using namespace std;
int main() {
string phone_number = "03-1234-5678";
// 1. 検索パターンを正規表現で定義
// (\\d{2,4}): 2〜4桁の数字 (キャプチャグループ)
regex pattern(R"((\d{2,4})-(\d{4})-(\d{4}))");
// 2. マッチ結果を格納するsmatchオブジェクトを準備
smatch matches;
// 3. regex_matchで、文字列全体がパターンに一致するか検証
if (regex_match(phone_number, matches, pattern)) {
cout << "文字列「" << phone_number << "」は、電話番号の形式にマッチしました。" << endl;
// 4. マッチした各部分を取り出す
cout << "マッチ全体: " << matches[0] << endl;
cout << "市外局番: " << matches[1] << endl;
cout << "市内局番: " << matches[2] << endl;
cout << "加入者番号: " << matches[3] << endl;
} else {
cout << "文字列「" << phone_number << "」は、指定された形式にマッチしませんでした。" << endl;
}
return 0;
}
コードの解説
1. regex pattern(...)
検索したいパターンを表現する正規表現オブジェクトを作成します。R"(...)"
(Raw文字列リテラル)を使うと、\
をエスケープする必要がなく便利です。()
で囲んだ部分はキャプチャグループとなり、後から参照できます。
2. smatch matches;
std::smatch
は、**std::string
**に対する正規表現のマッチ結果を格納するための特別なコンテナです。マッチした部分文字列(サブマッチ)がここに格納されます。
3. regex_match(phone_number, matches, pattern)
- 機能: 第1引数の文字列全体が、第3引数の正規表現パターンに完全に一致する場合にのみ
true
を返します。(文字列の一部分だけがマッチしてもfalse
になります) - 引数:
- 第1引数 (
phone_number
): 対象の文字列。 - 第2引数 (
matches
): マッチ結果を格納するsmatch
オブジェクト。 - 第3引数 (
pattern
): 正規表現パターン。
- 第1引数 (
- 戻り値: マッチしたかどうかを
bool
値で返します。
4. matches[n]
マッチが成功した場合、smatch
オブジェクト matches
には、以下のように結果が格納されます。
matches[0]
: マッチした文字列全体。matches[1]
: 1番目のキャプチャグループ(\d{2,4})
に一致した部分。matches[2]
: 2番目のキャプチャグループ(\d{4})
に一致した部分。matches[3]
: 3番目のキャプチャグループ(\d{4})
に一致した部分。
まとめ
今回は、C++の std::regex_match
を使って、文字列全体のフォーマット検証と、部分文字列の抽出を行う方法を解説しました。
std::regex_match
は、文字列全体との完全一致を判定する。std::regex
で、()
を使ってキャプチャグループを定義する。std::smatch
オブジェクトで、マッチ結果と各キャプチャグループの内容を受け取る。
regex_match
は、入力値のバリデーション(妥当性検証)を行う際に、非常に強力なツールとなります。