正規表現 (C++/CLI)
.NET Framework の正規表現クラスを使用したさまざまな文字列操作について説明します。
次のトピックでは、.NET Framework の System.Text.RegularExpressions 名前空間 (1 つのケースでは System.String.Split メソッド) を使用して文字列を検索、解析、変更する方法について説明します。
正規表現を使用して文字列を解析する
Regex 名前空間の System.Text.RegularExpressions クラスを使用して単純な文字列を解析する方法を次のコード例に示します。 複数のワード デリニエイタの型を含む文字列が構成されます。 次に、Regex クラスを Match クラスと共に使用して文字列が解析されます。 さらに、センテンス内の各単語を個別に表示します。
例
// regex_parse.cpp
// compile with: /clr
#using <system.dll>
using namespace System;
using namespace System::Text::RegularExpressions;
int main( )
{
int words = 0;
String^ pattern = "[a-zA-Z]*";
Console::WriteLine( "pattern : '{0}'", pattern );
Regex^ regex = gcnew Regex( pattern );
String^ line = "one\ttwo three:four,five six seven";
Console::WriteLine( "text : '{0}'", line );
for( Match^ match = regex->Match( line );
match->Success; match = match->NextMatch( ) )
{
if( match->Value->Length > 0 )
{
words++;
Console::WriteLine( "{0}", match->Value );
}
}
Console::WriteLine( "Number of Words : {0}", words );
return 0;
}
Split メソッドを使用して文字列を解析する
System.String.Split メソッドを使用して、文字列から各単語を抽出する方法を次のコード例に示します。 デリニエイタ リストを指定して Split を呼び出すと、複数の型のワード デリニエイタを含む文字列が構成され、解析されます。 さらに、センテンス内の各単語を個別に表示します。
例
// regex_split.cpp
// compile with: /clr
using namespace System;
int main()
{
String^ delimStr = " ,.:\t";
Console::WriteLine( "delimiter : '{0}'", delimStr );
array<Char>^ delimiter = delimStr->ToCharArray( );
array<String^>^ words;
String^ line = "one\ttwo three:four,five six seven";
Console::WriteLine( "text : '{0}'", line );
words = line->Split( delimiter );
Console::WriteLine( "Number of Words : {0}", words->Length );
for (int word=0; word<words->Length; word++)
Console::WriteLine( "{0}", words[word] );
return 0;
}
正規表現を使用して単純検索を行う
次のコード例は、正規表現を使用して、部分文字列の完全一致を検索する方法を示します。 検索は、入力として 2 つの文字列を受け取る静的な IsMatch メソッドによって実行されます。 1 つ目は検索する文字列、2 つ目は検索するパターンです。
例
// regex_simple.cpp
// compile with: /clr
#using <System.dll>
using namespace System;
using namespace System::Text::RegularExpressions;
int main()
{
array<String^>^ sentence =
{
"cow over the moon",
"Betsy the Cow",
"cowering in the corner",
"no match here"
};
String^ matchStr = "cow";
for (int i=0; i<sentence->Length; i++)
{
Console::Write( "{0,24}", sentence[i] );
if ( Regex::IsMatch( sentence[i], matchStr,
RegexOptions::IgnoreCase ) )
Console::WriteLine(" (match for '{0}' found)", matchStr);
else
Console::WriteLine("");
}
return 0;
}
正規表現を使用してデータ フィールドを抽出する
次のコード例は、正規表現を使用して、書式設定された文字列からデータを抽出する方法を示します。 次のコード例では、Regex クラスを使用して、電子メール アドレスに対応するパターンを指定します。 このパターンには、各電子メール アドレスのユーザーとホスト名の部分を取得するために使用できるフィールド識別子が含まれています。 Match クラスは、実際のパターン マッチングを実行するために使用されます。 指定した電子メール アドレスが有効な場合は、ユーザー名とホスト名が抽出され、表示されます。
例
// Regex_extract.cpp
// compile with: /clr
#using <System.dll>
using namespace System;
using namespace System::Text::RegularExpressions;
int main()
{
array<String^>^ address=
{
"jay@southridgevideo.com",
"barry@adatum.com",
"treyresearch.net",
"karen@proseware.com"
};
Regex^ emailregex = gcnew Regex("(?<user>[^@]+)@(?<host>.+)");
for (int i=0; i<address->Length; i++)
{
Match^ m = emailregex->Match( address[i] );
Console::Write("\n{0,25}", address[i]);
if ( m->Success )
{
Console::Write(" User='{0}'",
m->Groups["user"]->Value);
Console::Write(" Host='{0}'",
m->Groups["host"]->Value);
}
else
Console::Write(" (invalid email address)");
}
Console::WriteLine("");
return 0;
}
正規表現を使用してデータを再配置する
次のコード例は、.NET Framework の正規表現を使用して、データを再配置する (再フォーマットする) 方法を示します。 次のコード例では、Regex クラスと Match クラスを使用して、文字列から名前と姓を抽出してから、それらの名前要素を逆の順序で表示します。
Regex クラスは、データの現在の形式を記述する正規表現を構築するために使用されます。 2 つの名前はコンマで区切られていると見なされ、コンマの前後に任意の数の空白を使用できます。 その後、各文字列を分析するのに、Match メソッドが使用されます。 成功すると、名前と姓が Match オブジェクトから取得され、表示されます。
例
// regex_reorder.cpp
// compile with: /clr
#using <System.dll>
using namespace System;
using namespace Text::RegularExpressions;
int main()
{
array<String^>^ name =
{
"Abolrous, Sam",
"Berg,Matt",
"Berry , Jo",
"www.contoso.com"
};
Regex^ reg = gcnew Regex("(?<last>\\w*)\\s*,\\s*(?<first>\\w*)");
for ( int i=0; i < name->Length; i++ )
{
Console::Write( "{0,-20}", name[i] );
Match^ m = reg->Match( name[i] );
if ( m->Success )
{
String^ first = m->Groups["first"]->Value;
String^ last = m->Groups["last"]->Value;
Console::WriteLine("{0} {1}", first, last);
}
else
Console::WriteLine("(invalid)");
}
return 0;
}
正規表現を使用して検索と置換を行う
次のコード例は、正規表現クラス Regex を使用して検索と置換を実行する方法を示します。 これは次の Replace メソッドで実行されます。 使用されるバージョンでは、変更される文字列と、セクションの代わりに挿入される、Regex オブジェクトに指定したパターンに一致する文字列 (ある場合) の、2 つの文字列を入力として受け取ります。
このコードによって、文字列内のすべての数字がアンダースコア (_) に置き換えられ、その後それらが空の文字列に置き換えられることで、効果的に削除されます。 同じ効果を 1 つのステップで達成できますが、ここではデモンストレーション目的で 2 つのステップを使用します。
例
// regex_replace.cpp
// compile with: /clr
#using <System.dll>
using namespace System::Text::RegularExpressions;
using namespace System;
int main()
{
String^ before = "The q43uick bro254wn f0ox ju4mped";
Console::WriteLine("original : {0}", before);
Regex^ digitRegex = gcnew Regex("(?<digit>[0-9])");
String^ after = digitRegex->Replace(before, "_");
Console::WriteLine("1st regex : {0}", after);
Regex^ underbarRegex = gcnew Regex("_");
String^ after2 = underbarRegex->Replace(after, "");
Console::WriteLine("2nd regex : {0}", after2);
return 0;
}
正規表現を使用してデータ書式設定を検証する
次のコード例は、正規表現を使用して、文字列の書式設定を検証する方法を示します。 次のコード例では、文字列に有効な電話番号が含まれている必要があります。 次のコード例は、文字列 "\d{3}-\d{3}-\d{4}" を使用して、各フィールドが有効な電話番号を表すことを示します。 文字列内の "d" は数字を示し、各 "d" の後の引数は、存在する必要がある数字の数を示します。 この場合、数字がダッシュで区切られている必要があります。
例
// regex_validate.cpp
// compile with: /clr
#using <System.dll>
using namespace System;
using namespace Text::RegularExpressions;
int main()
{
array<String^>^ number =
{
"123-456-7890",
"444-234-22450",
"690-203-6578",
"146-893-232",
"146-839-2322",
"4007-295-1111",
"407-295-1111",
"407-2-5555",
};
String^ regStr = "^\\d{3}-\\d{3}-\\d{4}$";
for ( int i = 0; i < number->Length; i++ )
{
Console::Write( "{0,14}", number[i] );
if ( Regex::IsMatch( number[i], regStr ) )
Console::WriteLine(" - valid");
else
Console::WriteLine(" - invalid");
}
return 0;
}