C++Builder XEのTRegExで正規表現を使用する

C++Builder XEのTRegExで正規表現を使用する方法を調べました。

RegularExpressions.TRegExレコード

TRegExは、オープンソースのPCREライブラリのラッパーです。

RegularExpressionsユニットをincludeして使用します。

#include <RegularExpressions.hpp>

IsMatchメソッド 入力文字列に一致が存在するか

クラスメソッドを使う例

if (TRegEx::IsMatch("Delphi", "[A-Z]+"))
    ShowMessage("Match");

インスタンスメソッドを使う例

TRegEx regex("[A-Z]+");
if (regex.IsMatch("Delphi"))
  ShowMessage("Match");

Matcheメソッド 正規表現に一致する最初の文字列を取得する

MatcheメソッドTMatchレコードを返します。

クラスメソッドを使う例

TMatch match = TRegEx::Match("Delphi XE", "[A-Z]+");
ShowMessage(
  Format("%s (%d, %d)",
    ARRAYOFCONST((match.Value, match.Index, match.Length)))); //=> D (1, 1)

インスタンスメソッドを使う例

TRegEx regex("[A-Z]+");
TMatch match = regex.Match("Delphi XE");
ShowMessage(
  Format("%s (%d, %d)",
    ARRAYOFCONST((match.Value, match.Index, match.Length)))); //=> D (1, 1)

TMatchのNextMatchメソッドで次の一致した文字列を取得できます。

TRegEx regex("[A-Z]+");
TMatch match = regex.Match("Delphi XE");
ShowMessage(
  Format("%s (%d, %d)",
    ARRAYOFCONST((match.Value, match.Index, match.Length)))); //=> D (1, 1)

//次の一致
match = match.NextMatch();
ShowMessage(
  Format("%s (%d, %d)",
    ARRAYOFCONST((match.Value, match.Index, match.Length)))); //=> XE (8, 2)

TMatchのSuccessプロパティで一致したかどうかを調べることができます。

TRegEx regex("[A-Z]+");
TMatch match = regex.Match("Delphi XE");
while (match.Success)
{
  ShowMessage(match.Value);
  match = match.NextMatch();
}

グループ化した正規表現に一致した文字列は、TMatchのGroupsプロパティで取得できます。

TMatch match = TRegEx::Match("2012/5/14", "(\\d+)/(\\d+)/(\\d)");
ShowMessage(match.Groups.Count); //=> 4

for (int i = 0; i< match.Groups.Count; ++i)
{
  TGroup group = match.Groups[i];
  ShowMessage(Format("%s (%d, %d)",
    ARRAYOFCONST((group.Value, group.Index, group.Length))));
}
/* 出力結果
2012/5/1 (1, 8)
2012 (1, 4)
5 (6, 1)
1 (8, 1)
*/

Matchesメソッド 正規表現に一致するすべての文字列を取得する

Matchesメソッドは、TMatchCollectionレコードを返します。

TMatchCollection matches = TRegEx::Matches("Delphi XE", "[A-Z]+");
ShowMessage(IntToStr(matches.Count));

TMatch match = matches.Item[0];
ShowMessage(
  Format("%s (%d, %d)",
    ARRAYOFCONST((match.Value, match.Index, match.Length)))); //=> D (1, 1)

match = matches.Item[1];
ShowMessage(
  Format("%s (%d, %d)",
    ARRAYOFCONST((match.Value, match.Index, match.Length)))); //=> XE (8, 2)

Replaceメソッド 正規表現に一致した文字列を置き換える

//アルファベットの大文字を_に置き換える
UnicodeString s = TRegEx::Replace("Delphi XE", "[A-Z]", "_");
ShowMessage(s); //=> _elphi __

引数に関数を渡すことで、マッチした文字にあわせて置換する文字を指定できます。

/* マッチした数値に1を加える */
UnicodeString __fastcall TForm1::IncNum(const TMatch& Match)
{
  TMatch m = Match;
  return IntToStr(StrToInt(m.Value) + 1);
}

//正規表現に一致した文字を関数処理して置き換える
UnicodeString s = TRegEx::Replace("Delphi 2009", "\\d+", IncNum);
ShowMessage(s); //=> Delphi 2010

Splitメソッド 文字列を分割する

//半角スペースかスラッシュで分割する
TStringDynArray splits = TRegEx::Split("Delphi C++Builder/RadPHP", "[ /]");
for (int i = 0; i < splits.Length; ++i)
  Memo1->Lines->Add(splits[i]);

Escapeメソッド 特殊文字をエスケープする

UnicodeString s = TRegEx::Escape("C++");
ShowMessage(s); //=> C\+\+

■正規表現の文法を検証する

コンストラクタの引数にroCompiledを指定すると、正規表現をコンパイルします。
正規表現に問題があれば例外を投げます。

try {
  TRegEx regex("*", TRegExOptions() << roCompiled);
} catch (Exception &E) {
  ShowMessage(E.Message);
  //=>オフセット 0 で正規表現にエラーがあります: nothing to repeat
}

コメント

  1. Pingback: C++Builder XEでSkRegExpを使って正規表現を使用する « 山本隆の開発日誌

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください