クイック スタート
チュートリアル
ツール & 言語
リファレンス
書籍レビュー
正規表現ツール
grep
PowerGREP
RegexBuddy
RegexMagic
一般的なアプリケーション
EditPad Lite
EditPad Pro
言語 & ライブラリ
Boost
Delphi
GNU (Linux)
Groovy
Java
JavaScript
.NET
PCRE (C/C++)
PCRE2 (C/C++)
Perl
PHP
POSIX
PowerShell
Python
R
Ruby
std::regex
Tcl
VBScript
Visual Basic 6
wxWidgets
XML Schema
Xojo
XQuery & XPath
XRegExp
データベース
MySQL
Oracle
PostgreSQL
このサイトについて
はじめに
正規表現クイックスタート
正規表現チュートリアル
置換文字列チュートリアル
アプリケーションと言語
正規表現の例
正規表現リファレンス
置換文字列リファレンス
書籍レビュー
印刷用PDF
このサイトについて
RSSフィード & ブログ
RegexBuddy—The best regex editor and tester for C++ developers!

std::regex を使用した C++ の正規表現

C++11 標準で定義されている C++ 標準ライブラリは、<regex>ヘッダーで正規表現のサポートを提供しています。C++11 より前は、<regex>は C++ 標準ライブラリへの TR1 拡張の一部でした。このウェブサイトで std::regex と言及する場合、これは Visual C++ 2008 以降に含まれる C++ 標準ライブラリの Dinkumware 実装を指します。また、Win64 をターゲットとする場合、C++Builder XE3 以降でもサポートされています。Visual C++ 2008 では、名前空間は std::regex ではなく std::tr1::regex です。

C++Builder 10 以降は、従来の Borland コンパイラを使用するオプションを無効にすると、Win32 をターゲットとする場合に Dinkumware 実装の std::regex をサポートします。C++Builder XE3 以降で従来の Borland コンパイラを使用する場合は、std::regex の代わりに boost::regex を使用できます。TR1 および C++11 で定義されている std::regex は、boost::regex とほぼ同じ操作とクラスを定義していますが、実際の正規表現のフレーバーにはいくつかの重要な違いがあります。最も重要なのは、Boost の ECMAScript 正規表現構文が、ECMAScript 標準の一部ではなく、Dinkumware ライブラリに実装されていない、Perl から借用した多くの機能を追加することです。

6 つの正規表現フレーバー

std::regex_constants で 6 つの異なる正規表現フレーバーまたは文法が定義されています。

ほとんどの C++ リファレンスでは、C++11 は ECMA-262v3 および POSIX 標準で定義されているように正規表現を実装しているかのように説明しています。しかし実際には、C++ の実装はこれらの標準に非常に緩やかに基づいています。構文はかなり近いものです。唯一の大きな違いは、std::regex が ECMAScript モードでも POSIX クラスをサポートしていることと、どの文字をエスケープする必要があるか(中括弧や閉じ角括弧など)と、どの文字をエスケープしてはいけないか(文字など)について少し独特であることです。

しかし、この構文の実際の動作には重要な違いがあります。キャレットとドルは常に std::regex の埋め込み改行で一致しますが、JavaScript と POSIX ではこれはオプションです。不参加グループへの後方参照は、ほとんどの正規表現フレーバーと同様に一致に失敗しますが、JavaScript ではゼロ長の一致が見つかります。JavaScript では、\d\wは ASCII のみですが、\sはすべての Unicode 空白に一致します。これは奇妙ですが、すべての最新のブラウザーは仕様に従います。std::regex では、省略形はすべて、charの文字列を使用すると ASCII のみになります。Visual C++ では、C++Builder ではありませんが、wchar_tの文字列を使用すると Unicode をサポートします。POSIX クラスも、Visual C++ でwchar_tを使用すると非 ASCII 文字に一致しますが、期待されるすべての Unicode 文字が必ずしも含まれているわけではありません。

実際には、ほとんどの場合 ECMAScript 文法を使用することになります。これはデフォルトの文法であり、他の文法よりもはるかに多くの機能を提供します。このウェブサイトのチュートリアルで、文法について言及せずに std::regex について言及する場合は、記述されていることは ECMAScript 文法に適用され、他の文法のいずれにも適用される場合と適用されない場合があります。POSIX コードや UNIX スクリプトからの既存の正規表現を再利用したい場合にのみ、他の文法を使用することになります。

正規表現オブジェクトの作成

正規表現を使用する前に、テンプレート クラス std::basic_regex のオブジェクトを作成する必要があります。対象がcharの配列または std::string オブジェクトの場合、このテンプレート クラスの std::regex インスタンスを使用して簡単に作成できます。対象がwchar_tの配列または std::wstring オブジェクトの場合は、std::wregex インスタンスを使用します。

正規表現を文字列としてコンストラクターの最初のパラメーターとして渡します。ECMAScript 以外の正規表現フレーバーを使用する場合は、適切な定数を 2 番目のパラメーターとして渡します。この定数を std::regex_constants::icase と "or" 演算して正規表現を大文字と小文字を区別しないようにできます。また、std::regex_constants::nosubs と "or" 演算して、すべてのキャプチャ グループを非キャプチャ グループに変換することもできます。これにより、全体の正規表現の一致のみに関心があり、キャプチャ グループによって一致したテキストを抽出したくない場合に、正規表現の効率が向上します。

正規表現の一致の検索

正規表現が文字列の任意の部分に一致するかどうかを確認するには、対象文字列を最初のパラメーターとして、正規表現オブジェクトを 2 番目のパラメーターとして std::regex_search() を呼び出します。正規表現が対象文字列全体に一致するかどうかを確認する場合は、同じパラメーターで std::regex_match() を呼び出します。std::regex には文字列の先頭と末尾にのみ一致するアンカーがないため、正規表現を使用してユーザー入力を検証する場合は regex_match() を呼び出す必要があります。

regex_search() と regex_match() はどちらも、true または false のみを返します。regex_search() によって一致した文字列の部分を取得したり、どちらかの関数を使用した場合にキャプチャ グループによって一致した文字列の部分を取得したりするには、テンプレート クラス std::match_results のオブジェクトを 2 番目のパラメーターとして渡す必要があります。正規表現オブジェクトは 3 番目のパラメーターになります。このオブジェクトは、次の 4 つのテンプレート インスタンスのいずれかのデフォルト コンストラクターを使用して作成します。

の配列の場合は std::wcmatch

対象が std::wstring オブジェクトの場合は std::wsmatch

std::string subject("Name: John Doe");
std::string result;
try {
  std::regex re("Name: (.*)");
  std::smatch match;
  if (std::regex_search(subject, match, re) && match.size() > 1) {
    result = match.str(1);
  } else {
    result = std::string("");
  }
} catch (std::regex_error& e) {
  // Syntax error in the regular expression
}

関数呼び出しが true を返す場合は、match_results オブジェクトの str()、position()、length() メンバー関数を呼び出して、一致したテキスト、または対象文字列に対する一致の開始位置とその長さを取得できます。これらのメンバー関数をパラメーターなしで、またはパラメーターとして 0 を渡して呼び出して、全体の正規表現の一致を取得します。1 以上の値を渡して呼び出して、特定のキャプチャ グループの一致を取得します。size() メンバー関数は、全体のサイズに 1 を加えたキャプチャ グループの数を示します。したがって、他の 3 つのメンバー関数に size()-1 までの値を渡すことができます。

すべてをまとめると、次のように最初のキャプチャ グループで一致したテキストを取得できます。

対象が std::string オブジェクトの場合は std::sregex_iterator

std::string subject("This is a test");
try {
  std::regex re("\\w+");
  std::sregex_iterator next(subject.begin(), subject.end(), re);
  std::sregex_iterator end;
  while (next != end) {
    std::smatch match = *next;
    std::cout << match.str() << "\n";
    next++;
  }
} catch (std::regex_error& e) {
  // Syntax error in the regular expression
}

対象が

の配列の場合は std::wcregex_iterator

対象が std::wstring オブジェクトの場合は std::wsregex_iterator$&検索の開始位置を示す文字列イテレーター、検索の終了位置を示す文字列イテレーター、および正規表現オブジェクトの 3 つのパラメーターを指定してコンストラクターを呼び出して、1 つのオブジェクトを構築します。一致が見つかる場合は、オブジェクトは構築時に最初の一致を保持します。デフォルト コンストラクターを使用して別のイテレーター オブジェクトを構築して、シーケンスの終わりイテレーターを取得します。最初オブジェクトを 2 番目のオブジェクトと比較して、それ以上のマッチがあるかどうかを判断できます。最初のオブジェクトが 2 番目のオブジェクトと等しくない限り、最初のオブジェクトを逆参照して match_results オブジェクトを取得できます。$0すべての一致の置換$1文字列内のすべての一致を置換するには、対象文字列を最初のパラメーターとして、正規表現オブジェクトを 2 番目のパラメーターとして、置換テキストを含む文字列を 3 番目のパラメーターとして std::regex_replace() を呼び出します。この関数は、置換が適用された新しい文字列を返します。$9置換文字列構文は、JavaScript の構文に似ていますが、同一ではありません。どの正規表現構文または文法を使用しているかに関係なく、同じ置換文字列構文が使用されます。$`または$'を使用して、正規表現の一致全体を挿入できます。

から

| grep | PowerGREP | RegexBuddy | RegexMagic |

| EditPad Lite | EditPad Pro |

| Boost | Delphi | GNU (Linux) | Groovy | Java | JavaScript | .NET | PCRE (C/C++) | PCRE2 (C/C++) | Perl | PHP | POSIX | PowerShell | Python | R | Ruby | std::regex | Tcl | VBScript | Visual Basic 6 | wxWidgets | XML Schema | Xojo | XQuery & XPath | XRegExp |

| MySQL | Oracle | PostgreSQL |