2010-11-12T03:36:05の更新内容

programming/netfx/regex/0_abstract/index.wiki.txt

current previous
1,1521 1,342
 
${smdncms:title,正規表現の基本}
${smdncms:title,正規表現の基本}
~
${smdncms:keywords,Regex,IsMatch,Match,Matches,Split,Replace}
${smdncms:keywords,Regex}
 
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,.net framework}
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,.net framework}
 

                

                
 
#navi(..)
#navi(..)
~

                  
(このドキュメントは再構成中です)
+
正規表現とは、複数のファイル指定などで用いられるワイルドカード文字などのように、文字列の中から''特定のパターン''に一致する部分を検索したり、置き換えたりするためのものです。
+

                  
+
正規表現という名称からは難しい概念のように見えますが、実際のところはワイルドカードと同じように一連のルールが定められた''パターンを表現する一種の言語''です。 正規表現では、「httpで始まる文字列」や「途中に3桁以上の数値が含まれる文字列」というようなパターンを記号的に表記します。 例えば"*.txt"というワイルドカードでは「.txtで終わる(拡張子がtxtである)全てのファイル」を表しますが、正規表現もこれと似たような表現をします。
 

                

                
 
#googleadunit(rect)
#googleadunit(rect)
 

                

                
~
*.NET Frameworkの正規表現
*Regexクラスと正規表現
~
.NET Frameworkでは、&msdn(netfx,ns,System.Text.RegularExpressions){System.Text.RegularExpressions名前空間};にあるクラス群を使うことで正規表現に関する機能を使うことが出来ます。 このうち&msdn(netfx,type,System.Text.RegularExpressions.Regex){Regexクラス};は正規表現を使った操作を行うためのクラスで、このクラスを使うことで正規表現を使った比較・検索・置換などを行うことが出来ます。
早速ですが、Regexクラスを利用して正規表現とはどのようなものかを見ていくことにします。 次のコードは指定された正規表現のパターンが文字列の中に含まれるかをRegexクラスによって調べるコードです。
+

                  
+
また、これらのクラスで実装されている正規表現エンジン、および使用される文法はPerlなどで使用される正規表現とほぼ互換のものとなっています。 PerlやRubyでは正規表現は言語の機能として提供されますが、.NET Frameworkでは個々の言語に組み込まれた機能ではなくクラスライブラリの形で提供されるため、どの言語でも同じ文法で正規表現の機能を使用することが出来ます。 詳しくはMSDNの以下のドキュメントで解説されています。
+
-&msdn(netfx,id,hs600312){.NET Framework の正規表現};
+
--&msdn(netfx,id,e347654k){正規表現の動作の詳細};
+
--&msdn(netfx,id,az24scfc){正規表現言語要素};
+

                  
+
*正規表現とRegexクラス
+
正規表現を使った文字列操作を行う上で基本となるクラスが&msdn(netfx,type,System.Text.RegularExpressions.Regex){Regexクラス};です。 このクラスにはいくつかのメソッドが用意されていて、目的に応じて次のメソッドを使うことが出来ます。
+

                  
+
:[[IsMatchメソッド>#Regex.IsMatch]]|正規表現に''マッチする箇所があるかどうか''のみを調べたい場合に用いる。 戻り値はbool。
+
:[[Matchメソッド>#Regex.Match]]|正規表現に''マッチする最初の箇所''のみを取得したい場合などに用いる。 戻り値はMatch。
+
:[[Matchesメソッド>#Regex.Matches]]|正規表現に''マッチするすべての箇所''を取得したい場合に用いる。 戻り値はMatchCollection。
+
:[[Splitメソッド>#Regex.Split]]|正規表現に''マッチする箇所で分割''したい場合に用いる。 戻り値はstringの配列。
+
:[[Replaceメソッド>#Regex.Replace]]|正規表現に''マッチする箇所を別の文字列に置換''したい場合に用いる。 戻り値はstring。
+

                  
+
Regexクラスでは正規表現を指定してインスタンスを作成することが出来ますが、これらのメソッドはインスタンスを作成しなくても呼び出すことが出来ます。 インスタンスを作成した場合は、Regexインスタンス自体が正規表現を表すことになります。
+

                  
+
また、必要に応じてオプション(RegexOptions)を指定することによりこれらのメソッドの動作を変更することが出来ます。 詳しくは[[programming/netfx/regex/1_operations#RegexOptions]]にて解説します。
+

                  
+
*&aname(Regex.IsMatch){正規表現を用いた比較}; (Regex.IsMatch)
+
早速、Regexクラスを使って正規表現を用いた比較を行う例を見ていきます。 次のコードでは、いくつかのファイル名について".txt"で終わるかどうかを調べる例です。 正規表現との違いを見るために、String.EndsWithメソッドを使った例も併記しています。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
    };
+

                  
+
    foreach (string file in files)
+
    {
+
      Console.Write("{0,-20} ", file);
+

                  
+
      // Regexクラスと正規表現を使って比較
+
      if (Regex.IsMatch(file, @"\.txt$"))
+
        Console.Write("O ");
+
      else
+
        Console.Write("X ");
+

                  
+
      // Stringクラスのメソッドを使って比較
+
      if (file.EndsWith(".txt"))
+
        Console.WriteLine("O ");
+
      else
+
        Console.WriteLine("X ");
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt" _
+
    }
+

                  
+
    For Each file As String In files
+
      Console.Write("{0,-20} ", file)
+

                  
+
      ' Regexクラスと正規表現を使って比較
+
      If Regex.IsMatch(file, "\.txt$") Then
+
        Console.Write("O ")
+
      Else
+
        Console.Write("X ")
+
      End If
+

                  
+
      ' Stringクラスのメソッドを使って比較
+
      If file.EndsWith(".txt") Then
+
        Console.WriteLine("O ")
+
      Else
+
        Console.WriteLine("X ")
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
sample.txt           O O 
+
sample.txt.bak       X X 
+
sample.cs            X X 
+
test.txt             O O 
+
}}
+

                  
+
この例で使用している&msdn(netfx,method,System.Text.RegularExpressions.Regex.IsMatch){Regex.IsMatchメソッド};は、指定された文字列と正規表現のパターンを比較して、一致(マッチ)する箇所があるかどうかを返すメソッドです。
+

                  
+
"\.txt$"は「文字列が.txtで終わるかどうか」を表す正規表現です。 正規表現では ''.'' (ピリオド)や ''$'' はそれぞれ特別な意味を持ちます。 そのためこの例では、 ''.'' (ピリオド)を正規表現の記号ではなく単なる文字(名前と拡張子の区切りの文字)として扱うよう ''\'' (バックスラッシュ) でエスケープしています。 また、''$'' は文字列の末尾(行末)を表す記号で、これを指定することで".txt"が文字列の末尾で一致するようにしています。 これを指定しなかった場合は、文字列中の任意の場所にある".txt"と一致するようになり、つまりこの例ではString.Containsと同様の結果になります。
+

                  
+
なお、C#では通常の文字列リテラルに含まれる ''\'' (バックスラッシュ)はエスケープシーケンスとして認識されます。 そのため、正規表現のエスケープを行う場合には注意が必要です。 この例では、文字列リテラルの前に ''@'' (アットマーク)を付けることでエスケープシーケンスとして解釈させないようにしています。 もちろん"\\.txt$"のようにバックスラッシュを重ねて記述する方法をとることも出来ます。 必要に応じて、[[Regexクラスのメソッドを使ってエスケープ>#escape_pattern]]することも出来ます。
+

                  
+
**静的メソッドとインスタンスメソッド
+
Regexクラスではインスタンスを作成してパターンマッチングを行うことも出来ます。 IsMatchメソッドやMatchメソッドなどインスタンスメソッドと静的メソッドでほぼ同じメソッドが用意されていて、呼び出し方と結果においては違いはありません。 次の例は、先のコードを変更してRegexクラスのインスタンスを使ってファイル名が".txt"で終わるかどうかを調べるようにしたものです。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
    };
+

                  
+
    // パターンを指定してRegexクラスのインスタンスを作成
+
    Regex txtFilePattern = new Regex(@"\.txt$");
+

                  
+
    foreach (string file in files)
+
    {
+
      Console.Write("{0,-20} ", file);
+

                  
+
      if (txtFilePattern.IsMatch(file))
+
        Console.WriteLine("O ");
+
      else
+
        Console.WriteLine("X ");
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt" _
+
    }
+

                  
+
    ' パターンを指定してRegexクラスのインスタンスを作成
+
    Dim txtFilePattern As New Regex("\.txt$")
+
    
+
    For Each file As String In files
+
      Console.Write("{0,-20} ", file)
+

                  
+
      If txtFilePattern.IsMatch(file) Then
+
        Console.WriteLine("O ")
+
      Else
+
        Console.WriteLine("X ")
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
sample.txt           O 
+
sample.txt.bak       X 
+
sample.cs            X 
+
test.txt             O 
+
}}
+

                  
+
このようにインスタンスメソッドと静的メソッドでは呼び出し方と結果に違いはありませんが、パフォーマンスと内部の動作には違いがあります。 この点については[[programming/netfx/regex/1_operations#cached_regex]]で詳しく解説します。
+

                  
+
なお、Regexクラスは不変であるため、インスタンスとして作成した正規表現は後から変更することは出来ません。 Regexインスタンスが表す正規表現を取得するには、ToStringメソッドを呼び出します。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    Regex txtFilePattern = new Regex(@"\.txt$");
+

                  
+
    Console.WriteLine("pattern: {0}", txtFilePattern.ToString());
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim txtFilePattern As New Regex("\.txt$")
+

                  
+
    Console.WriteLine("pattern: {0}", txtFilePattern.ToString())
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
pattern: \.txt$
+
}}
+

                  
+
*正規表現を用いた検索
+
**&aname(Regex.Match){Regex.Match};
+
IsMatchメソッドでは正規表現にマッチするかどうかのみを知ることが出来ますが、&msdn(netfx,method,System.Text.RegularExpressions.Regex.Match){Regex.Matchメソッド};を使うとマッチした箇所のインデックスやマッチした文字列を取得することが出来ます。
+

                  
+
次のコードでは、いくつかのファイル名について ''.'' (ピリオド)以降を拡張子と見なす正規表現を使い、マッチした場合はその拡張子を表示しています。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
      "test.jpeg",
+
      "README",
+
    };
+

                  
+
    foreach (string file in files)
+
    {
+
      Console.Write("{0,-20} ", file);
+

                  
+
      // マッチする箇所を検索
+
      Match m = Regex.Match(file, @"\..*");
+

                  
+
      if (m.Success)
+
        // マッチした場合
+
        Console.WriteLine("{0,-10} ({1}, {2})", m.Value, m.Index, m.Length);
+
      else
+
        // マッチしなかった場合
+
        Console.WriteLine("?");
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt", _
+
      "test.jpeg", _
+
      "README" _
+
    }
+

                  
+
    For Each file As String In files
+
      Console.Write("{0,-20} ", file)
+

                  
+
      ' マッチする箇所を検索
+
      Dim m As Match = Regex.Match(file, "\..*")
+

                  
+
      If m.Success
+
        ' マッチした場合
+
        Console.WriteLine("{0,-10} ({1}, {2})", m.Value, m.Index, m.Length)
+
      Else
+
        ' マッチしなかった場合
+
        Console.WriteLine("?")
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
sample.txt           .txt       (6, 4)
+
sample.txt.bak       .txt.bak   (6, 8)
+
sample.cs            .cs        (6, 3)
+
test.txt             .txt       (4, 4)
+
test.jpeg            .jpeg      (4, 5)
+
README               ?
+
}}
+

                  
+
この例で使用している正規表現"\..*"は、「ピリオド(''\.'')に続けて、任意の文字(''.'')が、0文字以上続く(''*'')箇所」にマッチする正規表現です。 これにより、文字列中にある拡張子に該当する箇所を検索しています。
+

                  
+
Regex.Matchメソッドは戻り値として&msdn(netfx,type,System.Text.RegularExpressions.Match){Matchクラス};のインスタンスを返します。 このインスタンスには、正規表現での検索結果に関する情報が含まれています。 Match.Succsssプロパティは正規表現にマッチした箇所があったかどうかを示します。 マッチした場合は、Match.Valueプロパティを参照することでマッチした部分の文字列を取得することが出来ます。 また、Match.Indexでマッチした箇所のインデックス、Match.Lengthでマッチした箇所の長さを取得する事も出来ます。
+

                  
+
**&aname(Regex.Matches){Regex.Matches};
+
Regex.Matchメソッドでは最初にマッチした箇所のみが返されますが、&msdn(netfx,method,System.Text.RegularExpressions.Regex.Matches){Regex.Matchesメソッド};ではマッチした箇所すべてを取得することが出来ます。 Regex.Matchesメソッドの戻り値は&msdn(netfx,type,System.Text.RegularExpressions.MatchCollection){MatchCollection};で、これはMatchクラスのコレクションです。 MatchCollectionには正規表現にマッチした箇所すべてに対応するMatchインスタンスが格納され、マッチする箇所がなければ空のMatchCollectionが返されます。
+

                  
+
次のコードでは、文字列中に含まれる4文字以上の単語を検索し、表示しています。
 

                

                
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
 
using System;
using System;
 
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
 

                

                
~
class Sample
namespace RegularExpressions
 
{
{
~
  static void Main()
    class RegularExpressions
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog すばしっこい 茶色の 狐は のろまな 犬を 飛び越える";
+

                  
+
    // マッチする箇所を検索
+
    MatchCollection matches = Regex.Matches(text, @"\w{4,}");
+

                  
+
    // マッチした箇所をひとつずつ列挙
+
    foreach (Match m in matches)
 
    {
    {
~
      Console.WriteLine("{0,-10} ({1}, {2})", m.Value, m.Index, m.Length);
        [STAThread]
~
    }
        static void Main(string[] args)
~
  }
        {
~
}
            // 検証の対象となる文字列
~
}}
            string input = "santamartaofthepeaceonthewww";
~
#tabpage(VB)
            
~
#code(vb){{
            // aの後に、aからzのいずれか一文字が並ぶという意味の正規表現
~
Imports System
            string pattern1 = "a[a-z]";
~
Imports System.Text.RegularExpressions
            
~

                  
            Console.Write( "指定されたパターン {0} と一致する文字列", pattern1 );
~
Class Sample
            
~
  Shared Sub Main()
            if ( Regex.IsMatch( input, pattern1 ) )
~
    Dim text As String = "The quick brown fox jumps over the lazy dog すばしっこい 茶色の 狐は のろまな 犬を 飛び越える"
            {
~

                  
                Console.WriteLine( "を発見しました。" );
~
    ' マッチする箇所を検索
            }
~
    Dim matches As MatchCollection = Regex.Matches(text, "\w{4,}")
            else
~

                  
            {
~
    ' マッチした箇所をひとつずつ列挙
                Console.WriteLine( "はありませんでした。" );
~
    For Each m As Match In matches
            }
+
      Console.WriteLine("{0,-10} ({1}, {2})", m.Value, m.Index, m.Length)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
quick      (4, 5)
+
brown      (10, 5)
+
jumps      (20, 5)
+
over       (26, 4)
+
lazy       (35, 4)
+
すばしっこい     (44, 6)
+
のろまな       (58, 4)
+
飛び越える      (66, 5)
+
}}
+

                  
+
この例で使用している正規表現"\w{4,}"は、「アルファベット・かな・漢字などの文字(''\w'')が、4文字以上続く(''{4,}'')箇所」にマッチする正規表現です。
+

                  
+
*&aname(patterns){正規表現のパターン};
+
**正規表現要素
+
既に述べたとおり、正規表現ではいくつかの記号が特別な意味を持ちます。 正規表現ではこれらはの正規表現言語要素を組み合わせて一つのパターンを作成します。 Regexクラスを通して使用できる正規表現言語要素については[[programming/netfx/regex/2_expressions]]でも詳しく解説しますが、この中でも基本的なもの・よく使われるものを以下の表に抜粋しておきます。 &msdn(netfx,type,System.Text.RegularExpressions.RegexOptions){RegexOptions};で指定したオプションによっては動作が変わるものもありますが、ここでは解説しません。
+

                  
+
|*よく使われる正規表現要素
+
|~正規表現要素|~要素のカテゴリ|~意味とマッチする箇所|~パターンとマッチの例|h
+
|~['''chars''']|文字クラス|'''chars'''に含まれる任意の一文字|{{
+
[aeiou]
+

                  
+
a, e, i, o, uいずれかの文字にマッチ
+
}}|
+
|~[^'''chars''']|文字クラス|'''chars'''に含まれない任意の一文字|{{
+
[^aeiou]
+

                  
+
a, e, i, o, u以外の文字にマッチ
+
}}|
+
|~['''first'''-'''last''']|文字クラス|{{
+
'''first'''から'''last'''までの範囲に含まれる任意の一文字
+
[^'''first'''-'''last''']とした場合は'''first'''から'''last'''までの範囲に''含まれない''任意の一文字となる
+
}}|{{
+
[a-z0-9]
+

                  
+
aからzまでと0から9までの文字にマッチ
+
大文字のA-Zなどはマッチしない
+
}}|
+
|~. (ピリオド)|文字クラス|任意の一文字|{{
+
a.c
+

                  
+
aに続けて任意の一文字があり、さらにcが続く箇所にマッチ
+
マッチするのはaac, abc, axc…など
+
}}|
+
|~*|量指定子|直前の文字が0文字以上連続する箇所|{{
+
abc*
+

                  
+
a, bに続けてcが0文字以上連続する箇所にマッチ
+
マッチするのはab, abc, abcc…など
+
}}|
+
|~+|量指定子|直前の文字が1文字以上連続する箇所|{{
+
abc+
+

                  
+
a, bに続けてcが1文字以上連続する箇所にマッチ
+
マッチするのはabc, abcc, abccc…など
+
}}|
+
|~?|量指定子|直前の文字が0または1文字連続する箇所|{{
+
abc?
+

                  
+
a, bに続けてcが続くか、または続かない箇所にマッチ
+
マッチするのはabまたはabc
+
}}|
+
|~{'''n'''}|量指定子|直前の文字が'''n'''文字連続する箇所|{{
+
abc{3}
+

                  
+
a, bに続けてcが3文字続く箇所にマッチ
+
マッチするのはabccc
+
}}|
+
|~{'''n''','''m'''}|量指定子|{{
+
直前の文字が'''n'''文字以上'''m'''文字以下連続する箇所
+
'''m'''を省略して{'''n''',}とした場合は'''n'''文字以上となる。 '''n'''は省略できない。
+
}}|{{
+
abc{2,4}
+

                  
+
a, bに続けてcが2~4文字続く箇所にマッチ
+
マッチするのはabcc, abccc, abcccc
+
}}|
+
|~('''regex''')|グループ|{{
+
'''regex'''にマッチした箇所を一つの''グループ''として''キャプチャ''する
+
また、他の正規表現との優先順位を変更する際にも使用する
+

                  
+
グループとキャプチャについては[[programming/netfx/regex/1_operations]]で解説します
+
}}|{{
+
([a-z]+)
+

                  
+
[a-z]+にマッチする箇所を一つのグループとみなす
+
}}|
+
|~||選択・条件分岐|{{
+
|で区切られた正規表現のいずれかに一致する箇所
+
左側から優先してマッチする
+
}}|{{
+
a|an|(T|t)he
+

                  
+
マッチするのはa, an, the, Theのいずれか
+
}}|
+
|~^|アトミックゼロ幅アサーション|文字列の先頭|{{
+
パターン"^x+"では次の文字列中の強調した箇所にマッチする
+

                  
+
&color(orangered){xx};33xxx33xx
+
}}|
+
|~$|アトミックゼロ幅アサーション|文字列の末尾|{{
+
パターン"x+$"では次の文字列中の強調した箇所にマッチする
+

                  
+
xx33xxx33&color(orangered){xx};
+
}}|
+
|~\b|アトミックゼロ幅アサーション|{{
+
単語の境界
+
(\Wと\wとの境界部分)
+
}}|{{
+
パターン"\bx+"では次の文字列中の強調した箇所にマッチする
+

                  
+
&color(orangered){xxx};yyyxxx &color(orangered){xx};yyxx.&color(orangered){xx};
+
}}|
+
|~\s&br;\S|文字クラス|{{
+
\sは空白を表すUnicode文字1文字
+
\Sは\s以外の任意の一文字
+

                  
+
(\sには半角空白・全角空白などのほか、タブ、改行文字なども含まれる)
+
}}||
+
|~\w&br;\W|文字クラス|{{
+
\wは単語に使用されるUnicode文字1文字
+
\Wは\w以外の任意の1文字
+

                  
+
(\wにはアルファベット・かな・漢字・数字のほか、アンダーバーなどいくつかの記号も含まれる)
+
}}|{{
+
\wには次の文字列中の強調した文字が該当する
+

                  
+
&color(orangered){abc123_};+!&&color(orangered){あいう漢字123一二三};『!☆&color(orangered){〆々};
+
}}|
+
|~\d&br;\D|文字クラス|{{
+
\dは10進表記の数字に使用されるUnicode文字1文字
+
\Dは\d以外の任意の1文字
+

                  
+
(\dには半角数字だけでなく、全角数字も含まれる)
+
}}|{{
+
\dには次の文字列中の強調した文字が該当する
+

                  
+
abc&color(orangered){123};_+!&あいう漢字&color(orangered){123};一二三『!☆〆々
+
}}|
+
|~\p{'''category'''}&br;\P{'''category'''}|文字クラス|{{
+
\pは'''category'''のUnicodeカテゴリに該当する文字1文字
+
\Pは\p以外の任意の1文字('''category'''のUnicodeカテゴリに該当しない文字1文字)
+
}}|{{
+
それぞれのカテゴリには、次の文字列中の強調した文字が該当する
+

                  
+
\p{S} (記号)
+
abc123_&color(orangered){+};!&あいう漢字123一二三『!&color(orangered){☆};〆々
+

                  
+
\p{P} (句読点)
+
abc123&color(orangered){_};+&color(orangered){!&};あいう漢字123一二三&color(orangered){『!};☆〆々
+

                  
+
\p{IsHiragana} (ひらがな)
+
abc123_+!&&color(orangered){あいう};漢字123一二三『!☆〆々
+

                  
+
\p{IsCJKUnifiedIdeographs} (CJK統合漢字)
+
abc123_+!&あいう&color(orangered){漢字};123&color(orangered){一二三};『!☆〆々
+
}}|
+
|~\'''char'''|文字のエスケープ|{{
+
文字'''char'''のエスケープ表現
+
正規表現要素で使われる文字を通常の文字としてエスケープする場合に用いる
+

                  
+
(\t, \r, \n, \wなどはエスケープではなく文字・文字クラスとして扱われる点に注意)
+
}}|\\は ''\'' (バックスラッシュ)を表す|
+
|~\u'''xxxx'''|文字のエスケープ|4桁の16進数'''xxxx'''で表されるUnicode文字||
+
|~\x'''xx'''|文字のエスケープ|2桁の16数'''xxx'''で表されるASCII文字&br;"\u0020" = "\x20"||
+
|~正規表現要素|~要素のカテゴリ|~意味とマッチする箇所|~パターンとマッチの例|f
+

                  
+
この表にある正規表現要素の詳細については、MSDNの&msdn(netfx,id,az24scfc){正規表現言語要素};も参照してください。
+

                  
+
**パターンの例
+
次の例で使用している正規表現"^[aeiou][a-z]*"は、母音で始まる単語にマッチします。 この正規表現は、文字列の先頭(''^'')に続けて母音(''[aeiou]'')が一文字あり、以降任意のアルファベットが0文字以上(''[a-z]*'')続く文字列とマッチします。 ''^''が無い場合は、文字列の途中からでもマッチしてしまう点に注意してください。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] words = new string[] {
+
      "The",
+
      "quick",
+
      "brown",
+
      "fox",
+
      "jumps",
+
      "over",
+
      "the",
+
      "lazy",
+
      "dog",
+
    };
 

                

                
~
    foreach (string word in words)
            // aからzのいずれか一文字の後にxが並ぶという意味の正規表現
~
    {
            string pattern2 = "[a-z]x";
+
      Console.Write("{0,-20} ", word);
 

                

                
~
      if (Regex.IsMatch(word, "^[aeiou][a-z]*"))
            Console.Write( "指定されたパターン {0} と一致する文字列", pattern2 );
~
        Console.WriteLine("O");
            
~
      else
            if ( Regex.IsMatch( input, pattern2 ) )
~
        Console.WriteLine("X");
            {
-
                Console.WriteLine( "を発見しました。" );
-
            }
-
            else
-
            {
-
                Console.WriteLine( "はありませんでした。" );
-
            }
-
        }
 
    }
    }
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim words() As String = New String() { _
+
      "The", _
+
      "quick", _
+
      "brown", _
+
      "fox", _
+
      "jumps", _
+
      "over", _
+
      "the", _
+
      "lazy", _
+
      "dog" _
+
    }
 

                

                
~
    For Each word As String In words
#prompt(実行結果){{
~
      Console.Write("{0,-20} ", word)
指定されたパターン a[a-z] と一致する文字列を発見しました。
~

                  
指定されたパターン [a-z]x と一致する文字列はありませんでした。
~
      If Regex.IsMatch(word, "^[aeiou][a-z]*")
Press any key to continue
+
        Console.WriteLine("O")
+
      Else
+
        Console.WriteLine("X")
+
      End If
+
    Next
+
  End Sub
+
End Class
 
}}
}}
+
#tabpage-end
 

                

                
~
#prompt{{
この例からわかるとおり、RegexクラスのIsMatch()メソッドにより指定されたパターンが、文字列の中に含まれるかを調べることができます。 この例では共有メソッドを使いましたが、場合によってはRegexのインスタンスを作成してから各メソッドを利用することができます。 また、この例では単純な正規表現のパターンを利用しましたが、その他のパターンも含めてこの次で説明します。
+
The                  X
+
quick                X
+
brown                X
+
fox                  X
+
jumps                X
+
over                 O
+
the                  X
+
lazy                 X
+
dog                  X
+
}}
 

                

                
~
次の例で使用している正規表現"\d{1,3}(\.\d{1,3}){3}(/\d{1,2})?"は、IPアドレス(IPv4)となりうる文字列にマッチします。 この正規表現は、1~3桁の数字(''\d{1,3}'')に続けて、ピリオドと1~3桁の数字の組み合わせが三回続き(''(\.\d{1,3}){3}'')、場合によってはスラッシュと1~2桁の数字が後続する(''(/\d{1,2})?'')文字列にマッチします。
*正規表現のパターン
~

                  
正規表現ではいくつかのパターン(正規表現言語)を組み合わせて一つのパターンとします。 つまり、パターンによって表現の規則を定めるわけです。 正規表現言語のうち、最もよく使われるものを抜粋しておきます。 それらをカテゴリに分類し、そのカテゴリに含まれるパターン及び機能とその使用例を次の表にまとめます。 (.NET Framrworkで使用できるパターンと詳細については[[programming/netfx/regex/2_expressions]]で解説しています)
+
この正規表現ではIPアドレスとしては不正な形式の文字列にもマッチします。 ''\d'' を使っているため全角数字にもマッチする、''\d{1,3}'' には"999"などの数字もマッチする、''^'' を使っていないため文字列の途中でもマッチする点に注意してください。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
 

                

                
~
class Sample
|*文字クラス&br;任意の文字や文字のグループを表現するために用いる
~
{
|パターン|機能|使用例|h
~
  static void Main()
|.&br;(ドット)|改行以外の任意の一文字と一致する||
~
  {
|[ ]|かぎ括弧の中に含まれる任意の一文字と一致する|[abc]はa,b,cのいずれか一文字と一致する|
~
    string[] words = new string[] {
|[^ ]|かぎ括弧の中に含まれない任意の一文字と一致する|[^abc]はa,b,cのいずれか以外の一文字と一致する|
~
      "0.0.0.0/8",
|-|文字の範囲を表す|[a-zA-Z]は大文字小文字双方のAからZ、つまりアルファベットのいずれか一文字と一致する|
~
      "127.0.0.1",
|\w|アルファベット、数字、アンダーバーのいずれか一文字と一致する。 [a-zA-Z0-9_]と等価。||
~
      "192.168.1.1",
|\W|\w以外の一文字。 [^a-zA-Z0-9_]と等価。||
~
      "192.168.0.0/16",
|\d|十進の数字の一文字。 [0-9]と等価。||
~
      "255.255.255.255",
|\D|\d以外の一文字。 [^0-9]と等価。||
~
      "new IPAddress(\"192.168.1.1\")",
|\s|空白と一致する一文字。 スペース、タブ、改行など。 [\f\n\r\t\v]と等価。 これらのエスケープ文字については追って説明する。||
~
      "localhost",
|\S|\s以外の一文字。 [^\f\n\r\t\v]と等価。||
+
      "192.168.000.000",
+
      "192.168.999.999",
+
      "192.168.999.999/99",
+
      "3.141593",
+
      "2010.11.11",
+
      "127.0.0.1",
+
    };
 

                

                
~
    foreach (string word in words)
|*エスケープ&br;表示できない文字や、正規表現のパターンに用いられている文字と一致する場合に用いる
~
    {
|パターン|機能|使用例|h
~
      Console.Write("{0,-30} ", word);
|\XXX|八進で表されたASCII文字一文字。 XXXに三桁の八進の数字を指定する。|\040 はスペースと一致する|
-
|\xXX|十六進で表されたASCII文字一文字。 XXに二桁の十六進の数字を指定する。|\x20 はスペースと一致する|
-
|\uXXXX|十六進で表されたUnicode文字一文字。 XXXXに四桁の十六進の数字を指定する。|\u0020 はスペースと一致する|
-
|\cC|ASCII制御文字。|\cZ はCtrl + Z キーと一致する|
-
|\a|ベル音と一致する。|\x07と等価|
-
|\b|かぎ括弧の間で使用された場合はバックスペース、それ以外の場合は単語の境界と一致する。|バックスペースの場合は\x08と等価|
-
|\t|タブ文字と一致する。|\x09と等価|
-
|\r|キャリッジリターンと一致する。|\x0aと等価|
-
|\v|垂直タブ文字と一致する。|\x0bと等価|
-
|\f|フォームフィード文字と一致する。|\x0cと等価|
-
|\n|改行文字と一致する。|\x0dと等価|
-
|\e|エスケープ文字と一致する。|\x1eと等価|
-
|\□|□にある任意の一文字と一致する。|\*は*一文字、\\は\一文字と一致する|
 

                

                
~
      if (Regex.IsMatch(word, @"\d{1,3}(\.\d{1,3}){3}(/\d{1,2})?"))
|*量指定子&br;文字の連続する回数などを指定するために用いる
~
        Console.WriteLine("O");
|パターン|機能|使用例|h
~
      else
|*|0個以上連続した文字列と一致する|.* は全ての文字と一致する|
~
        Console.WriteLine("X");
|+|1個以上連続した文字列と一致する|\w+ は一文字以上のアルファベットの連続と一致する|
~
    }
|?|0個または1個の連続した文字列と一致する|aa? はaまたはaaと一致する|
~
  }
|{n}|n個の連続した文字列と一致する|\d{5} は5桁の数字と一致する|
~
}
|{n,}|少なくともn個の連続した文字列と一致する|\d{3,} は3桁以上の数字と一致する|
~
}}
|{n,m}|n個以上m個以下の連続した文字列と一致する|\d{3,5} は3桁以上5桁以下の数字と一致する|
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim words() As String = New String() { _
+
      "0.0.0.0/8", _
+
      "127.0.0.1", _
+
      "192.168.1.1", _
+
      "192.168.0.0/16", _
+
      "255.255.255.255", _
+
      "new IPAddress(""192.168.1.1"")", _
+
      "localhost", _
+
      "192.168.000.000", _
+
      "192.168.999.999", _
+
      "192.168.999.999/99", _
+
      "3.141593", _
+
      "2010.11.11", _
+
      "127.0.0.1" _
+
    }
 

                

                
~
    For Each word As String In words
|*その他
~
      Console.Write("{0,-30} ", word)
|パターン|機能|使用例|h
-
|()|()内の文字列を一つの文字と見なす。 また、優先順位を変更する際にも用いる。|(abc){3}はabcabcabcという文字列と一致する|
-
|||で区切られた文字のいずれかと一致する。 一番左から優先される。|VB(6|.NET)はVB6またはVB.NETのいずれかの文字列と一致する|
 

                

                
~
      If Regex.IsMatch(word, "\d{1,3}(\.\d{1,3}){3}(/\d{1,2})?")
ちなみに、C#では\は単体ではエスケープ文字として扱われてしまうので、実際には "\\w\\b" などのようにします。 それか、文字列リテラルの前に@を付けることでエスケープ文字を解釈させない事もできます。
+
        Console.WriteLine("O")
+
      Else
+
        Console.WriteLine("X")
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
それでは、これらのうちいくつかを利用して、文字列の検索をしてみようと思います。
+
0.0.0.0/8                      O
+
127.0.0.1                      O
+
192.168.1.1                    O
+
192.168.0.0/16                 O
+
255.255.255.255                O
+
new IPAddress("192.168.1.1")   O
+
localhost                      X
+
192.168.000.000                O
+
192.168.999.999                O
+
192.168.999.999/99             O
+
3.141593                       X
+
2010.11.11                     X
+
127.0.0.1                      O
+
}}
 

                

                
+
次の例で使用している正規表現"(\p{Ll}|\p{Lu})+|\p{IsHiragana}+|\p{IsKatakana}+|\p{IsCJKUnifiedIdeographs}+"は、アルファベット・ひらがな・カタカナ・漢字が連続する箇所にマッチします。 この正規表現は、小文字または大文字の連続(''(\p{Ll}|\p{Lu})+'')、ひらがなの連続(''\p{IsHiragana}+'')、カタカナの連続(''\p{IsKatakana}+'')、漢字の連続(''\p{IsCJKUnifiedIdeographs}+'')のいずれかにマッチします。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
 
using System;
using System;
 
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
 

                

                
~
class Sample
namespace RegularExpressions
 
{
{
~
  static void Main()
    class RegularExpressions
+
  {
+
    string text = "Regexにマッチした箇所を一つのグループとしてキャプチャする";
+
    string pattern = @"(\p{Ll}|\p{Lu})+|\p{IsHiragana}+|\p{IsKatakana}+|\p{IsCJKUnifiedIdeographs}+";
+

                  
+
    foreach (Match m in Regex.Matches(text, pattern))
+
    {
+
      Console.WriteLine(m.Value);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String ="Regexにマッチした箇所を一つのグループとしてキャプチャする"
+
    Dim pattern As String = "(\p{Ll}|\p{Lu})+|\p{IsHiragana}+|\p{IsKatakana}+|\p{IsCJKUnifiedIdeographs}+"
+

                  
+
    For Each m As Match In Regex.Matches(text, pattern)
+
      Console.WriteLine(m.Value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
Regex
+
+
マッチ
+
した
+
箇所
+
+
+
つの
+
グループ
+
として
+
キャプチャ
+
する
+
}}
+

                  
+
次の例で使用している正規表現"[\u3040-\u30ff]+"は、ひらがなとカタカナが連続する箇所にマッチします。 この正規表現は、ひらがな(U+3040~U+309F)およびカタカナ(U+30A0~U+30FF)に該当するコードポイントの文字(''[\u3040-\u30ff]'')が連続する(''+'')箇所にマッチします。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "Regexにマッチした箇所を一つのグループとしてキャプチャする";
+
    string pattern = @"[\u3040-\u30ff]+";
+

                  
+
    foreach (Match m in Regex.Matches(text, pattern))
 
    {
    {
~
      Console.WriteLine(m.Value);
        [STAThread]
~
    }
        static void Main(string[] args)
~
  }
        {
~
}
            // 検証の対象となる文字列、たとえば文字の羅列
~
}}
            string input = "santamartaofthepeaceonthewww";
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String ="Regexにマッチした箇所を一つのグループとしてキャプチャする"
+
    Dim pattern As String = "[\u3040-\u30ff]+"
+

                  
+
    For Each m As Match In Regex.Matches(text, pattern)
+
      Console.WriteLine(m.Value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
            // アルファベットの前半が三文字以上続く文字列
~
にマッチした
            RegexMatchAndOutput( input, "[a-n]{3,}" );
~
            
~
つのグループとしてキャプチャする
            // 母音で始まり、アルファベットの後半が一文字以上続く文字列
~
}}
            RegexMatchAndOutput( input, "[aeiou][o-z]+" );
 

                

                
~
**&aname(escape_pattern){パターンとエスケープ (Regex.Escape)};
            // of, onから始まる部分
~
正規表現要素として使われる文字にマッチさせたい場合は、文字をエスケープする必要があります。 エスケープする文字が多い場合などはパターン文字列中に ''\'' (バックスラッシュ) が多くなり読みにくくなります。 &msdn(netfx,method,System.Text.RegularExpressions.Regex.Espace){Regex.Escapeメソッド};を使うと、正規表現要素をエスケープした文字列を取得することができ、バックスラッシュを使わずにエスケープすることが出来ます。
            RegexMatchAndOutput( input, "(on|of).*" );
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
 

                

                
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "おはよー(*^o^*) 今日もよろしく(^_^)v";
+
    string pattern = "(*^o^*)"; // 正規表現要素を含むパターン
 

                

                
~
    Console.Write("{0} => ", pattern);
            Console.WriteLine();
 

                

                
+
    // Regex.Escapeメソッドでパターンをエスケープ
+
    pattern = Regex.Escape(pattern);
 

                

                
~
    Console.WriteLine(pattern);
            // たとえば英文 
-
            input = "This is a sample code for Regex class, used for regular expressions.";
 

                

                
~
    Console.WriteLine(text);
            // 大文字で始まる五文字以上の単語
-
            RegexMatchAndOutput( input, @"\b[A-Z]\w{4,}\b" );
-
            
-
            // sを含む単語
-
            RegexMatchAndOutput( input, @"\b\w*s\w*\b" );
-
            
-
            // rで終わる単語
-
            RegexMatchAndOutput( input, @"\b\w+r\b" );
 

                

                
+
    // Regex.Replaceメソッドで正規表現にマッチする箇所を置換
+
    Console.WriteLine(Regex.Replace(text, pattern, "(^ω^)"));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
 

                

                
~
Class Sample
            Console.WriteLine();
+
  Shared Sub Main()
+
    Dim text As String = "おはよー(*^o^*) 今日もよろしく(^_^)v"
+
    Dim pattern As String = "(*^o^*)" ' 正規表現要素を含むパターン
 

                

                
+
    Console.Write("{0} => ", pattern)
 

                

                
~
    ' Regex.Escapeメソッドでパターンをエスケープ
            // IPアドレスとなりうるパターン
~
    pattern = Regex.Escape(pattern)
            string pattern = @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}";
-
            
-
            RegexMatchAndOutput( "123.4.567.89", pattern );
 

                

                
~
    Console.WriteLine(pattern)
            RegexMatchAndOutput( "3.14159265358", pattern );
 

                

                
+
    Console.WriteLine(text)
 

                

                
~
    ' Regex.Replaceメソッドで正規表現にマッチする箇所を置換
            Console.WriteLine();
+
    Console.WriteLine(Regex.Replace(text, pattern, "(^ω^)"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
+
#prompt{{
+
(*^o^*) => \(\*\^o\^\*\)
+
おはよー(*^o^*) 今日もよろしく(^_^)v
+
おはよー(^ω^) 今日もよろしく(^_^)v
+
}}
 

                

                
~
Regex.Replaceメソッドによる置換については後ほど解説します。
            // メールアドレスとなりうるパターン
-
            pattern = @"[\w\-.]+@[\w\-.]+";
 

                

                
~
*正規表現を用いた文字列の加工
            RegexMatchAndOutput( "santamartaofthepeace@hotmail.com", pattern );
+
Regexクラスには、比較や検索の他に正規表現を用いて文字列を加工するメソッドも用意されています。
 

                

                
~
**&aname(Regex.Split){分割}; (Regex.Split)
            RegexMatchAndOutput( "In this case, @ means \'at\'.", pattern );
~
&msdn(netfx,method,System.Text.RegularExpressions.Regex.Split){Regex.Splitメソッド};を使うと、正規表現にマッチした箇所を区切りとして文字列を分割することが出来ます。 次の例では、句読点(''\p{P}'')を区切りとみなして文字列を分割しています。
        }
 

                

                
~
#tabpage(C#)
        // 正規表現にマッチする文字列を表示する
~
#code(cs){{
        static void RegexMatchAndOutput( string input, string pattern )
~
using System;
        {
~
using System.Text.RegularExpressions;
            // マッチする文字列の一覧
-
            MatchCollection matches;
-
            
-
            matches = Regex.Matches( input, pattern );
 

                

                
~
class Sample
            Console.WriteLine( "文字列: {0}   ", input );
+
{
+
  static void Main()
+
  {
+
    string text = "abc,def.ghi!あいう、アイウ。かな「漢字」カナ,123.123";
+
    string pattern = @"\p{P}";
 

                

                
~
    string[] words = Regex.Split(text, pattern);
            if ( 0 < matches.Count )
-
            {
-
                Console.WriteLine( "パターン: {0}", pattern );
-
                
-
                // 列挙
-
                foreach( Match match in matches )
-
                {
-
                    Console.WriteLine( "\t{0}", match.Value );
-
                }
-
            }
-
            else
-
            {
-
                Console.WriteLine( "パターン: {0} にマッチする文字列は見つかりませんでした。", pattern );
-
            }
-
        }
 

                

                
+
    Console.WriteLine("count: {0}", words.Length);
+

                  
+
    foreach (string word in words)
+
    {
+
      Console.WriteLine(word);
 
    }
    }
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String ="abc,def.ghi!あいう、アイウ。かな「漢字」カナ,123.123"
+
    Dim pattern As String = "\p{P}"
+

                  
+
    Dim words() As String = Regex.Split(text, pattern)
+

                  
+
    Console.WriteLine("count: {0}", words.Length)
+

                  
+
    For Each word As String In words
+
      Console.WriteLine(word)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
count: 10
+
abc
+
def
+
ghi
+
あいう
+
アイウ
+
かな
+
漢字
+
カナ
+
123
+
123
+
}}
 

                

                
~
また、次の例では、\r, \n, \r\nのいずれかを改行とみなして文字列を行毎に分割しています。
#prompt(実行結果){{
~

                  
文字列: santamartaofthepeaceonthewww
~
#tabpage(C#)
パターン: [a-n]{3,}
~
#code(cs){{
        ama
~
using System;
        eace
~
using System.Text.RegularExpressions;
文字列: santamartaofthepeaceonthewww
-
パターン: [aeiou][o-z]+
-
        art
-
        ao
-
        ep
-
        eo
-
        ewww
-
文字列: santamartaofthepeaceonthewww
-
パターン: (on|of).*
-
        ofthepeaceonthewww
 

                

                
~
class Sample
文字列: This is a sample code for Regex class, used for regular expressions.
~
{
パターン: \b[A-Z]\w{4,}\b
~
  static void Main()
        Regex
~
  {
文字列: This is a sample code for Regex class, used for regular expressions.
~
    string text = "1行目\r\n2行目\n3行目\r4行目\n\r6行目";
パターン: \b\w*s\w*\b
~
    string pattern = @"\r\n|\r|\n";
        This
~

                  
        is
~
    string[] lines = Regex.Split(text, pattern);
        sample
~

                  
        class
~
    Console.WriteLine("count: {0}", lines.Length);
        used
~

                  
        expression
~
    foreach (string line in lines)
文字列: This is a sample code for Regex class, used for regular expressions.
~
    {
パターン: \b\w+r\b
~
      Console.WriteLine(line);
        for
~
    }
        for
~
  }
        regular
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "1行目" + vbCrLf + "2行目" + vbLf + "3行目" + vbCr + "4行目" + vbLf + vbCr + "6行目"
+
    Dim pattern As String = "\r\n|\r|\n"
+

                  
+
    Dim lines() As String = Regex.Split(text, pattern)
+

                  
+
    Console.WriteLine("count: {0}", lines.Length)
+

                  
+
    For Each line As String In lines
+
      Console.WriteLine(line)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
文字列: 123.4.567.89
~
count: 6
パターン: \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
~
1行目
        123.4.567.89
~
2行目
文字列: 3.14159265358
~
3行目
パターン: \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} にマッチする文字列は見つかりませんでした。
+
4行目
 

                

                
~
6行目
文字列: santamartaofthepeace@hotmail.com
-
パターン: [\w\-.]+@[\w\-.]+
-
        santamartaofthepeace@hotmail.com
-
文字列: In this case, @ means 'at'.
-
パターン: [\w\-.]+@[\w\-.]+ にマッチする文字列は見つかりませんでした。
-
Press any key to continue
 
}}
}}
 

                

                
~
なお、\r, \n, \r\nによる分割はTextReaderを使うことでも行えます。 比較のために、StringReaderを使った行分割の例を挙げておきます。
まず、正規表現以外のソースコードの説明をします。 RegexMatchAndOutput()メソッドでは、指定された文字列に対して、その中から指定されたパターンにマッチする部分を抜き出し、表示するということをしています。 実際にそれを行っているのは、RegexクラスのMatches()メソッドです。 このメソッドの戻り値はMatchCollection型で、この中にマッチしたパターンを記述したMatchクラスのインスタンスが含まれます。 マッチする部分がない場合は何も含まれません。 これと似たメソッドにMatch()がありますが、これはマッチした部分をひとつだけ返します。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.IO;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "1行目\r\n2行目\n3行目\r4行目\n\r6行目";
+
    StringReader r = new StringReader(text);
+

                  
+
    for (;;)
+
    {
+
      string line = r.ReadLine();
+

                  
+
      if (line == null) break;
 

                

                
~
      Console.WriteLine(line);
そのほかの部分は説明するまでもないと思いますし、正規表現とその検索結果もソースコードと実行結果を見比べれば問題ないと思うので特に説明はしません。 ただ、正規表現を読んだり書いたりする場合は、一度日本語にするといいと思います。 たとえば、sを含む単語を検索する正規表現は「\b\w*s\w*\b」であるとしましたが、これを左から日本語に訳せば、「単語の境界から始まり(\b)、0個以上のアルファベット(\w*)に続いてsがあり、さらに0個以上のアルファベット(\w*)が続き、最後に再び単語の境界(\b)が現れるようなパターン」となります。 正規表現を書くときも一度パターンを日本語で表してからそれを順に正規表現に変えていけば容易にできると思います。
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.IO
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "1行目" + vbCrLf + "2行目" + vbLf + "3行目" + vbCr + "4行目" + vbLf + vbCr + "6行目"
+
    Dim r As New StringReader(text)
+

                  
+
    Do
+
      Dim line As String = r.ReadLine()
+

                  
+
      If line Is Nothing Then Exit Do
+

                  
+
      Console.WriteLine(line)
+
    Loop
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
**&aname(Regex.Replace){置換}; (Regex.Replace)
*Replace()メソッドによる置換
~
&msdn(netfx,method,System.Text.RegularExpressions.Regex.Replace){Regex.Replaceメソッド};を使うと正規表現にマッチした箇所を別の文字列に置換することが出来ます。 次の例では、拡張子の正規表現(''\..*'')にマッチする箇所を".bak"に置換しています。
正規表現によって任意のパターンの文字列を検索できるだけでもかなり利用価値がありますが、その検索されたパターンを用いて置き換えができればさらに便利なものといえるでしょう。 実際、それを行うためのメソッドがRegexクラスには用意されています。
 

                

                
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
 
using System;
using System;
 
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
 

                

                
~
class Sample
namespace RegularExpressions
 
{
{
~
  static void Main()
    class RegularExpressions
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
      "test.jpeg",
+
      "README",
+
    };
+

                  
+
    foreach (string file in files)
 
    {
    {
~
      Console.Write("{0,-20} => ", file);
        [STAThread]
-
        static void Main(string[] args)
-
        {
-
            // 置き換えの対象
-
            string input = "This is a sample code.";
-
            
-
            // 検索パターン
-
            string pattern = @"(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)";
-
            
-
            // 置き換えパターン
-
            string replacement = "$3 $4 $5 $1 $2";
 

                

                
~
      string bakFile = Regex.Replace(file, @"\..*", ".bak");
            // 置き換え結果
~

                  
            Console.WriteLine( Regex.Replace( input, pattern, replacement ) );
~
      Console.WriteLine(bakFile);
        }
 
    }
    }
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt", _
+
      "test.jpeg", _
+
      "README" _
+
    }
+

                  
+
    For Each file As String In files
+
      Console.Write("{0,-20} => ", file)
+

                  
+
      Dim bakFile As String = Regex.Replace(file, "\..*", ".bak")
 

                

                
~
      Console.WriteLine(bakFile)
#prompt(実行結果){{
~
    Next
a sample code This is
~
  End Sub
Press any key to continue
+
End Class
 
}}
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
sample.txt           => sample.bak
+
sample.txt.bak       => sample.bak
+
sample.cs            => sample.bak
+
test.txt             => test.bak
+
test.jpeg            => test.bak
+
README               => README
+
}}
+

                  
+
Regex.Replaceメソッドと&msdn(netfx,method,System.Text.RegularExpressions.Regex.MatchEvaluator){MatchEvaluatorデリゲート};を組み合わせて使うと、より高度な置換を行うことが出来ます。 このデリゲートでは、マッチした箇所(Matchクラス)を引数にとり、置換した結果を戻り値として返します。 次の例では、上記のコードを少し変更し、MatchEvaluatorデリゲートを使って拡張子に".bak"を追加して置換しています。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static string ChangeExtension(Match m)
+
  {
+
    if (m.Value.EndsWith(".bak"))
+
      // マッチした箇所が".bak"で終わる場合は、そのままにする
+
      return m.Value;
+
    else
+
      // そうでなければ、".bak"を追加する
+
      return m.Value + ".bak";
+
  }
+

                  
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
      "test.jpeg",
+
      "README",
+
    };
+

                  
+
    foreach (string file in files)
+
    {
+
      Console.Write("{0,-20} => ", file);
+

                  
+
      string bakFile = Regex.Replace(file, @"\..*", ChangeExtension);
+

                  
+
      Console.WriteLine(bakFile);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Function ChangeExtension(ByVal m As Match) As String
+
    If m.Value.EndsWith(".bak")
+
      ' マッチした箇所が".bak"で終わる場合は、そのままにする
+
      Return m.Value
+
    Else
+
      ' そうでなければ、".bak"を追加する
+
      Return m.Value + ".bak"
+
    End If
+
  End Function
+

                  
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt", _
+
      "test.jpeg", _
+
      "README" _
+
    }
 

                

                
~
    For Each file As String In files
このサンプルでは一見何が行われているかよくわからないかもしれませんが、名前からReplace()メソッドが実際の置き換えを行っているというのは想像できると思います。 ただ、置き換えに際して知っておくべきことがいくつかあります。 パターンを見てみると、「(\\w+)」のように括弧でくくられた部分がいくつかあるのがわかると思います。 この括弧でくくられた部分は「グループ」として扱われます。 この場合、「(\\w+)」となっているのでアルファベットの連続がひとつのグループとされ、正規表現全体では一つ一つのアルファベットの連続、つまり単語がグループとして扱われます。
+
      Console.Write("{0,-20} => ", file)
 

                

                
~
      Dim bakFile As String = Regex.Replace(file, "\..*", AddressOf ChangeExtension)
また、括弧によってグループ化される際にはそれぞれのグループに1から始まるグループ番号がつけられます。 ここで、グループ0は正規表現全体とマッチする文字列を表します。 続いて、置き換えパターンでは$nのように、$マークと序数がつけられています。 Replace()メソッドではこの$nの部分に対応する番号を持つグループの文字列が置き換えられます。 つまりこの場合は「1 2 3 4 5」と並んでいる単語を「3 4 5 1 2」と並び替えるのです。 並び替えた後も「.(ピリオド)」の位置が変わっていないのは、ピリオドに対してグループが作られなかったのと、それに対する置き換え文字列がないからです。
 

                

                
~
      Console.WriteLine(bakFile)
ただ、この例は非常に単純な置き換えを行うものです。 もう少し複雑な置き換えを行おうとすると、正規表現が複雑になり、括弧の量も増えるため、どこがどのグループなのか把握しづらくなります。 そこで、グループ名に名前を割り当てて置き換えを行うことができます。 次のコードはそれを利用したものです。
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
sample.txt           => sample.txt.bak
+
sample.txt.bak       => sample.txt.bak
+
sample.cs            => sample.cs.bak
+
test.txt             => test.txt.bak
+
test.jpeg            => test.jpeg.bak
+
README               => README
+
}}
 

                

                
+
Regex.Replaceメソッドで置換後の文字列を指定した場合、この文字列は単純な文字列ではなく正規表現として解釈され、''$'' で始まる正規表現要素を指定することが出来ます。 例えば ''$0'' は正規表現にマッチした文字列に置き換えられます。 次の例では、拡張子の正規表現にマッチした箇所(''$0'')に".bak"を追加して置換しています。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
 
using System;
using System;
 
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
 

                

                
~
class Sample
namespace RegularExpressions
 
{
{
~
  static void Main()
    class RegularExpressions
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
      "test.jpeg",
+
      "README",
+
    };
+

                  
+
    foreach (string file in files)
 
    {
    {
~
      Console.Write("{0,-20} => ", file);
        [STAThread]
~

                  
        static void Main(string[] args)
~
      string bakFile = Regex.Replace(file, @"\..*", "$0.bak");
        {
~

                  
            // 正規表現パターン
~
      Console.WriteLine(bakFile);
            string pattern = @"\b(dim)\s+(?<identifier>\w+)\s+(as)\s+(?<type>[\w.]+)\b";
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt", _
+
      "test.jpeg", _
+
      "README" _
+
    }
+

                  
+
    For Each file As String In files
+
      Console.Write("{0,-20} => ", file)
+

                  
+
      Dim bakFile As String = Regex.Replace(file, "\..*", "$0.bak")
+

                  
+
      Console.WriteLine(bakFile)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
sample.txt           => sample.txt.bak
+
sample.txt.bak       => sample.txt.bak.bak
+
sample.cs            => sample.cs.bak
+
test.txt             => test.txt.bak
+
test.jpeg            => test.jpeg.bak
+
README               => README
+
}}
+

                  
+
別の例を使って見てみます。 次の例では3文字の単語(''\b\w{3}\b'')にマッチした箇所(''$0'')を山括弧で括って置換する(''<$0>'')ようにしています。 なお、''\b'' を指定することで ''\w{3}'' が単語の途中にマッチしないようにしています。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog";
+

                  
+
    Console.WriteLine(Regex.Replace(text, @"\b\w{3}\b", "<$0>"));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+

                  
+
    Console.WriteLine(Regex.Replace(text, "\b\w{3}\b", "<$0>"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
<The> quick brown <fox> jumps over <the> lazy <dog>
+
}}
+

                  
+
MatchEvaluatorを使ってこれと同様の置換を行う場合は次のようになります。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
 

                

                
~
class Sample
            // 検索された文字列に対して置き換えるパターン
~
{
            string replacement = "${type} ${identifier};";
+
  static string AngleBracket(Match m)
+
  {
+
    return "<" + m.Value + ">";
+
  }
+

                  
+
  static void Main()
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog";
+

                  
+
    Console.WriteLine(Regex.Replace(text, @"\b\w{3}\b", AngleBracket));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Function AngleBracket(ByVal m As Match) As String
+
    Return "<" + m.Value + ">"
+
  End Function
+

                  
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+

                  
+
    Console.WriteLine(Regex.Replace(text, "\b\w{3}\b", AddressOf AngleBracket))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
''$0''以外にも置換に使える正規表現要素がありますが、詳しくは[[programming/netfx/regex/1_operations]]および[[programming/netfx/regex/2_expressions]]で解説します。
+

                  
+
*正規表現と大文字小文字の無視 (RegexOptions)
+
RegexクラスのIsMatch, Match, Matches, Split, Replaceの各メソッドは、マッチングの際の動作オプションを&msdn(netfx,type,System.Text.RegularExpressions.RegexOptions){RegexOptions列挙型};で指定することが出来るようになっています。 指定出来るオプションにはいくつかありますが、RegexOptions.IgnoreCaseを指定すると大文字と小文字の違いの無視するようになります。
+

                  
+
例えば次の例では、いくつかのファイル名について拡張子が".txt"かどうかを調べています。 比較のために、RegexOptions.IgnoreCaseを指定した場合と指定していない場合の結果を併記しています。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
 

                

                
~
class Sample
            // Regexクラスのインスタンスを作成 (検索の際、大文字小文字を無視)
~
{
            Regex r = new Regex( pattern, RegexOptions.IgnoreCase );
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "Sample.Txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
      "TEST.TXT",
+
      "test.HTML",
+
    };
 

                

                
~
    foreach (string file in files)
            // 置き換えて結果を表示
~
    {
            Console.WriteLine( r.Replace( "Dim i As Integer", replacement ) );
~
      Console.Write("{0,-20} ", file);
            Console.WriteLine( r.Replace( "Dim s As String", replacement ) );
~

                  
            Console.WriteLine( r.Replace( "Dim ui As System.UInt32", replacement ) );
~
      // 大文字小文字の違いを意識する
        }
+
      if (Regex.IsMatch(file, @"\.txt$"))
+
        Console.Write("O ");
+
      else
+
        Console.Write("X ");
+

                  
+
      // 大文字小文字の違いを無視する
+
      if (Regex.IsMatch(file, @"\.txt$", RegexOptions.IgnoreCase))
+
        Console.WriteLine("O ");
+
      else
+
        Console.WriteLine("X ");
 
    }
    }
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "Sample.Txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt", _
+
      "TEST.TXT", _
+
      "test.HTML" _
+
    }
 

                

                
~
    For Each file As String In files
#prompt(実行結果){{
~
      Console.Write("{0,-20} ", file)
Integer i;
~

                  
String s;
~
      ' 大文字小文字の違いを意識する
System.UInt32 ui;
~
      If Regex.IsMatch(file, "\.txt$") Then
Press any key to continue
+
        Console.Write("O ")
+
      Else
+
        Console.Write("X ")
+
      End If
+

                  
+
      ' 大文字小文字の違いを無視する
+
      If Regex.IsMatch(file, "\.txt$", RegexOptions.IgnoreCase) Then
+
        Console.WriteLine("O ")
+
      Else
+
        Console.WriteLine("X ")
+
      End If
+
    Next
+
  End Sub
+
End Class
 
}}
}}
+
#tabpage-end
 

                

                
~
#prompt{{
この例ではグループ化を「(<グループ名>正規表現)」という形式で行っています。 これによって括弧にくくられた部分がひとつのグループとして解釈され、同時に名前も割り当てられます。 置き換えの際は「${グループ名}」とするだけです。 後の構文は先ほどの置き換えの例とほとんど変わりありません。 ちなみに、このサンプルではVB風のローカル変数宣言をC言語風に置き換えています。
+
sample.txt           O O 
+
Sample.Txt           X O 
+
sample.txt.bak       X X 
+
sample.cs            X X 
+
test.txt             O O 
+
TEST.TXT             X O 
+
test.HTML            X X 
+
}}
 

                

                
~
RegexOptionsを使って指定できるオプションは他にもありますが、詳しくは[[programming/netfx/regex/1_operations#RegexOptions]]で解説します。
この例ではRegexクラスのインスタンスを作成していますが、同じ正規表現を何度も使う場合などにはこの例のようにインスタンスを作ってそれを利用したほうが効率的といえます。 また、インスタンス生成の際にオプションとして大文字・小文字の違いを無視するような設定をしています。 このほかにもいくつかオプションがありますが、ここではその説明はしません。
+

                  
+
なお、いくつかのオプションは正規表現の文字列(インラインオプション)として指定することも出来ます。 RegexOptions.IgnoreCaseは、インラインオプションでは ''(?i:'''regex''')'' と記述できます。 上記の例をインラインオプションを使って書き換えると次のようになります。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      "sample.txt",
+
      "Sample.Txt",
+
      "sample.txt.bak",
+
      "sample.cs",
+
      "test.txt",
+
      "TEST.TXT",
+
      "test.HTML",
+
    };
+

                  
+
    foreach (string file in files)
+
    {
+
      Console.Write("{0,-20} ", file);
+

                  
+
      // 大文字小文字の違いを意識する
+
      if (Regex.IsMatch(file, @"\.txt$"))
+
        Console.Write("O ");
+
      else
+
        Console.Write("X ");
+

                  
+
      // 大文字小文字の違いを無視する
+
      if (Regex.IsMatch(file, @"(?i:\.txt$)"))
+
        Console.WriteLine("O ");
+
      else
+
        Console.WriteLine("X ");
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "sample.txt", _
+
      "Sample.Txt", _
+
      "sample.txt.bak", _
+
      "sample.cs", _
+
      "test.txt", _
+
      "TEST.TXT", _
+
      "test.HTML" _
+
    }
+

                  
+
    For Each file As String In files
+
      Console.Write("{0,-20} ", file)
+

                  
+
      ' 大文字小文字の違いを意識する
+
      If Regex.IsMatch(file, "\.txt$") Then
+
        Console.Write("O ")
+
      Else
+
        Console.Write("X ")
+
      End If
+

                  
+
      ' 大文字小文字の違いを無視する
+
      If Regex.IsMatch(file, "(?i:\.txt$)") Then
+
        Console.WriteLine("O ")
+
      Else
+
        Console.WriteLine("X ")
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
 
#navi(..)
#navi(..)
 

                

                

programming/netfx/regex/1_operations/index.wiki.txt

current previous
1,1489 1,291
~
${smdncms:title,正規表現関連のクラスと機能}
${smdncms:title,正規表現クラスと操作}
~
${smdncms:keywords,Regex,RegexOptions,Match,Group,Capture,グループ,キャプチャ}
${smdncms:keywords,Regex,Match,Group,Capture}
 
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,.net framework}
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,.net framework}
 

                

                
 
#navi(..)
#navi(..)
~
&msdn(netfx,ns,System.Text.RegularExpressions){System.Text.RegularExpressions名前空間};には正規表現を表すRegexクラス以外にも関連するクラスおよび型がいくつかあります。 ここではその詳細について見ていきます。
(このドキュメントは再構成中です)
 

                

                
 
#googleadunit(rect)
#googleadunit(rect)
 

                

                
~
*Matchクラス
*Regexクラス
~
&msdn(netfx,type,System.Text.RegularExpressions.Match){Matchクラス};は正規表現にマッチした箇所(部分文字列)を表すクラスで、Regex.Matchメソッド・Regex.Matchesメソッドでの戻り値として返されます。
Regexクラスは正規表現のインスタンスを表し、入力文字列に対するマッチ箇所の検索・置換・分割を行うメソッドを持つ。 クラスメソッドを用いる場合はインスタンスを作成することなく検索・置換・分割を行うことが出来る。
-
**主なコンストラクタ
-
:Regex(string)|文字列で表された正規表現のインスタンスを作成する。
-
:Regex(string, RegexOptions)|正規表現エンジンの動作を指定するRegexOptionsを指定し、文字列で表された正規表現のインスタンスを作成する。
-

                  
-
**主なメソッド
-
:bool IsMatch(string)|入力文字列が正規表現にマッチするかどうかを表す値を返す。 正規表現にマッチする箇所があるかどうかだけ調べたい場合に用いる。
-
:Match Match(string)|入力文字列のうち、正規表現にマッチする最初の箇所を表すMatchを返す。 正規表現にマッチする最初の箇所だけを取得したい場合などに用いる。
-
:MatchCollection Matches(string)|入力文字列のうち、正規表現にマッチする箇所のコレクションを表すMatchCollectionを返す。 正規表現にマッチするすべての箇所を取得したい場合に用いる。
-
:string Replace(string, string)|入力文字列のうち、正規表現にマッチする箇所を置換文字列で置換した値を返す。 正規表現にマッチする箇所を置換したい場合に用いる。
-
:string Replace(string, MatchEvaluator)|入力文字列のうち、正規表現にマッチする箇所をMatchEvaluatorデリゲートの戻り値で置換した値を返す。 正規表現にマッチする箇所を置換文字列では表現しきれない形式に置換したい場合に用いる。
-
:string[] Split(string)|入力文字列を、正規表現にマッチする箇所で分割した配列を返す。 正規表現で表される区切り文字列で文字列を分割したい場合に用いる。
-

                  
-
以下はクラスメソッド。
-
:static bool IsMatch(string, string, RegexOptions)|入力文字列、正規表現文字列とオプションを引数に取る。 動作はインスタンスメソッドのIsMatchと同じ。
-
:static Match Match(string, string, RegexOptions)|入力文字列、正規表現文字列とオプションを引数に取る。 動作はインスタンスメソッドのMatchと同じ。
-
:static MatchCollection Matches(string, string, RegexOptions)|入力文字列、正規表現文字列とオプションを引数に取る。 動作はインスタンスメソッドのMatchesと同じ。
-
:static string Replace(string, string, string, RegexOptions)|入力文字列、正規表現文字列、置換文字列とオプションを引数に取る。 動作はインスタンスメソッドのReplaceと同じ。
-
:static string Replace(string, string, MatchEvaluator, RegexOptions)|入力文字列、正規表現文字列、MatchEvaluatorデリゲートとオプションを引数に取る。 動作はインスタンスメソッドのReplaceと同じ。
-
:static string[] Split(string, string, RegexOptions)|入力文字列、正規表現文字列とオプションを引数に取る。 動作はインスタンスメソッドのSplitと同じ。
-

                  
-
*Matchクラス、Groupクラス、Captureクラス
-
Matchクラス、Groupクラス、Captureクラスは正規表現にマッチした部分文字列を表す。 それぞれのクラスが表す部分文字列は次の通り。
-
:Matchクラス|Regexクラスで表される正規表現にマッチした箇所全体を表す。
-
:Groupクラス|Regexクラスで表される正規表現のグループにマッチした箇所を表す。
-
:Captureクラス|Regexクラスで表される正規表現の部分式にマッチした箇所を表す。
-

                  
-
MatchクラスはGroupクラスを包含し、GroupクラスはCaptureクラスを包含する。 包含するコレクションを表すプロパティは次の通り。
-
:Match.Groupsプロパティ|Matchが表す部分文字列中に含まれるGroupのコレクション(GroupCollection)を表す。
-
:Group.Capturesプロパティ|Groupが表す部分文字列中に含まれるCaptureのコレクション(CaptureCollection)を表す。
 

                

                
~
**NextMatchメソッド
また同時にMatchクラスはGroupクラス、GroupクラスはCaptureクラスを継承する。 継承関係をツリー形式で表すと次の通り。
~
&msdn(netfx,method,System.Text.RegularExpressions.Match.NextMatch){Match.NextMatchメソッド};は、同じ正規表現が次にマッチする箇所を返すメソッドで、このメソッドを使うとRegex.Matchesメソッドと同様にマッチする箇所を順に検索することが出来ます。 マッチする箇所が無い場合は、SuccessプロパティがfalseのMatchを返します。
-Captureクラス
~

                  
--Groupクラス
~
#tabpage(C#)
---Matchクラス
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog";
+
    string pattern = @"\w{4,}"; // 4文字以上の単語
+

                  
+
    Match m = Regex.Match(text, pattern); // 最初にマッチする箇所を取得
+

                  
+
    while (m.Success)
+
    {
+
      // マッチする箇所があった場合
+
      Console.WriteLine("{0,-10} ({1}, {2})", m.Value, m.Index, m.Length);
+

                  
+
      // 次にマッチする箇所を取得する
+
      m = m.NextMatch();
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+
    Dim pattern As String = "\w{4,}" ' 4文字以上の単語
+

                  
+
    Dim m As Match = Regex.Match(text, pattern) ' 最初にマッチする箇所を取得
+

                  
+
    Do While m.Success
+
      ' マッチする箇所があった場合
+
      Console.WriteLine("{0,-10} ({1}, {2})", m.Value, m.Index, m.Length)
+

                  
+
      ' 次にマッチする箇所を取得する
+
      m = m.NextMatch()
+
    Loop
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
それぞれのクラスに対応するコレクションクラスは次の通り。
~
quick      (4, 5)
-Matchクラス - MatchCollectionクラス
~
brown      (10, 5)
-Groupクラス - GroupCollectionクラス
~
jumps      (20, 5)
-Captureクラス - CaptureCollectionクラス
+
over       (26, 4)
+
lazy       (35, 4)
+
}}
 

                

                
~
**Resultメソッド
**Matchクラス、Groupクラス、Captureクラスの表す部分文字列
~
&msdn(netfx,method,System.Text.RegularExpressions.Match.Result){Match.Resultメソッド};は、マッチした箇所を引数で指定した置換文字列によって置換した結果を返します。 Regex.Replaceメソッドではマッチした箇所すべてに同一の置換文字列が適用されますが、Match.Resultメソッドを使うことでマッチする箇所に応じて置換文字列を指定することも出来ます。
例えば、"([A-Z])([a-z]+)"という正規表現では各クラスが表す部分文字列は次のようになる。
~

                  
:Matchクラス|"([A-Z])([a-z]+)"にマッチした箇所を表す部分文字列。
~
#tabpage(C#)
:Groupクラス|"([A-Z])"または"([a-z]+)"にマッチした箇所を表す部分文字列。
~
#code(cs){{
:Captureクラス|"[A-Z]"または"[a-z]+"にマッチした箇所を表す部分文字列。
+
using System;
+
using System.Text.RegularExpressions;
 

                

                
~
class Sample
上記の正規表現と入力文字列"Windows Vista"を例にとると、Matchクラスが表す箇所とインデックスは次のようになる。
~
{
 W i n d o w s   V i s t a
~
  static void Main()
 ~~~~~~~~~~~~~0
~
  {
                 ~~~~~~~~~1
~
    string text = "The quick brown fox jumps over the lazy dog";
同様にGroupクラスが表す箇所とMatchクラス内でのインデックスは次のようになる。 インデックス0のグループはマッチした箇所全体を表す点に注意。
~
    string pattern = @"\w{4,}"; // 4文字以上の単語
 W i n d o w s   V i s t a
~

                  
 ~~~~~~~~~~~~~0  ~~~~~~~~~0
~
    foreach (Match m in Regex.Matches(text, pattern))
 ~1              ~1
~
    {
   ~~~~~~~~~~~2    ~~~~~~~2
~
      Console.WriteLine("{0,-10} : {1}", m.Value, m.Result("$`<$0>"));
同様にCaptureクラスが表す箇所とGroupクラス内でのインデックスは次のようになる。
~
    }
 W i n d o w s   V i s t a
~
  }
 ~0              ~0
~
}
   ~~~~~~~~~~~0    ~~~~~~~0
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+
    Dim pattern As String = "\w{4,}" ' 4文字以上の単語
+

                  
+
    For Each m As Match In Regex.Matches(text, pattern)
+
      Console.WriteLine("{0,-10} : {1}", m.Value, m.Result("$`<$0>"))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
quick      : The <quick>
+
brown      : The quick <brown>
+
jumps      : The quick brown fox <jumps>
+
over       : The quick brown fox jumps <over>
+
lazy       : The quick brown fox jumps over the <lazy>
+
}}
+

                  
+
*Groupクラス
+
&msdn(netfx,type,System.Text.RegularExpressions.Group){Groupクラス};は正規表現要素 ''()'' でグループ化された箇所にマッチした部分を表すクラスです。 例えば、正規表現"(\w+)\s*(\w+)"の場合、この正規表現全体にマッチする文字列はMatchクラスに格納されますが、最初の"(\w+)"と次の"(\w+)"の部分にマッチする部分はそれぞれGroupクラスに格納されます。
+

                  
+
グループにマッチした部分文字列は、&msdn(netfx,member,System.Text.RegularExpressions.Match.Groups){Match.Groupsプロパティ};を通して参照することが出来ます。 正規表現中のグループ ''()'' の位置に応じて、1以降のインデックスが割り当てられます。 インデックスが0のグループは特殊なグループで、正規表現全体にマッチした部分を表します。
+

                  
+
次の例では、代入演算子の左辺と右辺をそれぞれグループ化した正規表現を使い、マッチした内容とグループの内容を表示しています。
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    Match m = Regex.Match("foo = 16;", @"\s*(\w+)\s*=\s*(\w+)");
+

                  
+
    Console.WriteLine("Match: {0}", m.Value);
+

                  
+
    Console.WriteLine("Groups[0]: {0}", m.Groups[0].Value);
+
    Console.WriteLine("Groups[1]: {0}", m.Groups[1].Value);
+
    Console.WriteLine("Groups[2]: {0}", m.Groups[2].Value);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim m As Match = Regex.Match("foo = 16;", "\s*(\w+)\s*=\s*(\w+)")
+

                  
+
    Console.WriteLine("Match: {0}", m.Value)
+

                  
+
    Console.WriteLine("Groups[0]: {0}", m.Groups(0).Value)
+
    Console.WriteLine("Groups[1]: {0}", m.Groups(1).Value)
+
    Console.WriteLine("Groups[2]: {0}", m.Groups(2).Value)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
**Matchクラスの主なメソッド
~
Match: foo = 16
:Match NextMatch()|次にマッチする箇所を表すMatchを返す。
~
Groups[0]: foo = 16
:string Result(string)|Matchクラスの値を指定した置換文字列で置換した結果を返す。
~
Groups[1]: foo
**Matchクラスの主なプロパティ
~
Groups[2]: 16
:GroupCollection Groups {get;}|正規表現にマッチしたグループのコレクションを表すGroupCollectionを取得する。
~
}}
:int Index {get;}|マッチした部分文字列の、入力文字列中のインデックスを取得する。 (Captureクラスから継承)
-
:int Length {get;}|マッチした部分文字列の長さを取得する。 (Captureクラスから継承)
-
:string Value {get;}|マッチした部分文字列を取得する。 (Captureクラスから継承)
-
:bool Success {get;}|マッチした箇所があるかどうかを取得する。 (Groupクラスから継承)
 

                

                
~
**グループと置換文字列
*RegexOptions列挙体
~
正規表現要素 ''()'' でグループされた箇所は、置換文字列でも参照することが出来ます。 置換文字列 ''$0'' はインデックス0のグループ(=マッチした文字列全体)、''$1'' はインデックス1のグループを表し、以降同様に ''$2''、''$3''…と参照することが出来ます。
RegexOptions列挙体はRegexクラスの動作を指定する。 一部のオプションは正規表現文字列内で一時的に変更することが出来る。
-
**RegexOptions列挙体のメンバ
-
:None|なし。 オプションを指定しない。
-
:IgnoreCase|インラインオプションi。 大文字小文字の違いを無視する。
-
:Multiline|インラインオプションm。 複数行モードにする(^と$がそれぞれ行頭と行末にもマッチする)。
-
:ExplicitCapture|インラインオプションn。 ('''subexpression''')をキャプチャしない(明示的に名前または番号を指定したグループのみをキャプチャする)。
-
:Singleline|インラインオプションs。 単一行モードにする(.が\nにもマッチする)。
-
:IgnorePatternWhitespace|インラインオプションx。 エスケープされない空白をパターンから除外し、#以降を行末までのコメントとして扱うように変更する。
-
:CultureInvariant|カルチャの違いを無視する。
-
:ECMAScript|ECMAScript互換の動作にする。
-
:RightToLeft|検索の方向を右から左にする。
-
:Compiled|正規表現をコンパイルし、MSILコードを生成する。
 

                

                
~
次の例では、先の例と同様の正規表現を使って代入式の左辺と右辺を入れ替えています。
*Regexクラスを用いたサンプル
-
Regexクラスの各メソッドを用いたサンプル。
 

                

                
~
#tabpage(C#)
**IsMatchメソッド
-
IsMatchメソッドを使ってファイルの拡張子が.htmlか判断する例。
 
#code(cs){{
#code(cs){{
~
using System;
var inputs = new[] {
~
using System.Text.RegularExpressions;
  "readme.txt",
-
  "index.html",
-
  "index.html.org",
-
  "INDEX.HTML",
-
  "index.xhtml",
-
};
-
var html = @"\.(?i:html)$";
 

                

                
~
class Sample
foreach (var input in inputs) {
~
{
  if (Regex.IsMatch(input, html))
~
  static void Main()
    Console.WriteLine("    HTML file : {0}", input);
~
  {
  else
~
    string[] lines = new string[] {
    Console.WriteLine("not HTML file : {0}", input);
+
      "foo = 16;",
+
      "  bar=42;",
+
      "baz = foo; // comment"
+
    };
+

                  
+
    foreach (string line in lines)
+
    {
+
      Console.WriteLine(Regex.Replace(line, @"\s*(\w+)\s*=\s*(\w+)", "$2 = $1"));
+
    }
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim lines() As String = New String() { _
+
      "foo = 16;", _
+
      "  bar=42;", _
+
      "baz = foo; // comment" _
+
    }
+

                  
+
    For Each line As String In lines
+
      Console.WriteLine(Regex.Replace(line, "\s*(\w+)\s*=\s*(\w+)", "$2 = $1"))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
#prompt(実行結果){{
~
16 = foo;
not HTML file : readme.txt
~
42 = bar;
    HTML file : index.html
~
foo = baz; // comment
not HTML file : index.html.org
-
    HTML file : INDEX.HTML
-
not HTML file : index.xhtml
 
}}
}}
 

                

                
~
比較のために、MatchEvaluatorデリゲートを使った例も載せておきます。
**Matchメソッド
~

                  
Matchメソッドを使って文字列中から3文字の単語を強調表示する例。
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "The quick brown fox jumps over the lazy dog";
~
using System.Text.RegularExpressions;
var word = @"\b\w{3}\b";
 

                

                
~
class Sample
for (var m = Regex.Match(input, word); m.Success; m = m.NextMatch()) {
~
{
  Console.WriteLine("{0}<{1}>{2}", input.Substring(0, m.Index), m.Value, input.Substring(m.Index + m.Length));
+
  static string Swap(Match m)
+
  {
+
    return string.Format("{0} = {1}", m.Groups[2].Value, m.Groups[1].Value);
+
  }
+

                  
+
  static void Main()
+
  {
+
    string[] lines = new string[] {
+
      "foo = 16;",
+
      "  bar=42;",
+
      "baz = foo; // comment"
+
    };
+

                  
+
    foreach (string line in lines)
+
    {
+
      Console.WriteLine(Regex.Replace(line, @"\s*(\w+)\s*=\s*(\w+)", Swap));
+
    }
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Function Swap(ByVal m As Match) As String
+
    Return String.Format("{0} = {1}", m.Groups(2).Value, m.Groups(1).Value)
+
  End Function
+

                  
+
  Shared Sub Main()
+
    Dim lines() As String = New String() { _
+
      "foo = 16;", _
+
      "  bar=42;", _
+
      "baz = foo; // comment" _
+
    }
 

                

                
~
    For Each line As String In lines
#prompt(実行結果){{
~
      Console.WriteLine(Regex.Replace(line, "\s*(\w+)\s*=\s*(\w+)", AddressOf Swap))
<The> quick brown fox jumps over the lazy dog
~
    Next
The quick brown <fox> jumps over the lazy dog
~
  End Sub
The quick brown fox jumps over <the> lazy dog
~
End Class
The quick brown fox jumps over the lazy <dog>
 
}}
}}
+
#tabpage-end
+

                  
+
**名前付きのグループ
+
正規表現要素 ''(?<'''name'''>)'' を使うと、グループに名前を付けることが出来ます。 置換文字列中で名前付きのグループを参照する場合は、''${'''name'''}''と記述します。
 

                

                
~
次のコードでは、先の例を書き換え、名前付きグループを使って左辺と右辺を入れ替えています。
上記の例をMatch.Resultメソッドを用いてより簡略に書き換えた例。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "The quick brown fox jumps over the lazy dog";
~
using System.Text.RegularExpressions;
var word = @"\b\w{3}\b";
 

                

                
~
class Sample
for (var m = Regex.Match(input, word); m.Success; m = m.NextMatch()) {
~
{
  Console.WriteLine(m.Result("$`<$0>$'"));
+
  static void Main()
+
  {
+
    string[] lines = new string[] {
+
      "foo = 16;",
+
      "  bar=42;",
+
      "baz = foo; // comment"
+
    };
+

                  
+
    foreach (string line in lines)
+
    {
+
      Console.WriteLine(Regex.Replace(line, @"\s*(?<left>\w+)\s*=\s*(?<right>\w+)", "${right} = ${left}"));
+
    }
+
  }
 
}
}
 
}}
}}
~
#tabpage(VB)
Regex.MatchメソッドおよびMatch.NextMatchメソッドの代わりに、Regex.Matchesメソッドを用いて書き換えると次のようになる。
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim lines() As String = New String() { _
+
      "foo = 16;", _
+
      "  bar=42;", _
+
      "baz = foo; // comment" _
+
    }
+

                  
+
    For Each line As String In lines
+
      Console.WriteLine(Regex.Replace(line, "\s*(?<left>\w+)\s*=\s*(?<right>\w+)", "${right} = ${left}"))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
16 = foo;
+
42 = bar;
+
foo = baz; // comment
+
}}
+

                  
+
また、Match.Groupsプロパティで名前付きグループを参照することも出来ます。 この場合、インデクサにはインデックスの代わりにグループ名を指定します。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "The quick brown fox jumps over the lazy dog";
~
using System.Text.RegularExpressions;
var word = @"\b\w{3}\b";
+

                  
+
class Sample
+
{
+
  static string Swap(Match m)
+
  {
+
    return string.Format("{0} = {1}", m.Groups["right"].Value, m.Groups["left"].Value);
+
  }
 

                

                
~
  static void Main()
foreach (Match m in Regex.Matches(input, word)) {
~
  {
  Console.WriteLine(m.Result("$`<$0>$'"));
+
    string[] lines = new string[] {
+
      "foo = 16;",
+
      "  bar=42;",
+
      "baz = foo; // comment"
+
    };
+

                  
+
    foreach (string line in lines)
+
    {
+
      Console.WriteLine(Regex.Replace(line, @"\s*(?<left>\w+)\s*=\s*(?<right>\w+)", Swap));
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Function Swap(ByVal m As Match) As String
+
    Return String.Format("{0} = {1}", m.Groups("right").Value, m.Groups("left").Value)
+
  End Function
+

                  
+
  Shared Sub Main()
+
    Dim lines() As String = New String() { _
+
      "foo = 16;", _
+
      "  bar=42;", _
+
      "baz = foo; // comment" _
+
    }
+

                  
+
    For Each line As String In lines
+
      Console.WriteLine(Regex.Replace(line, "\s*(?<left>\w+)\s*=\s*(?<right>\w+)", AddressOf Swap))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
*Match・Group・Capture
+
**Match・Group・Captureの表す部分文字列
+
Matchクラス・Groupクラスの他に、マッチした箇所の部分文字列を表すクラスとして&msdn(netfx,type,System.Text.RegularExpressions.Capture){Captureクラス};があります。 それぞれのクラスが表す部分文字列は次のようになります。
+

                  
+
:Match|正規表現にマッチした箇所全体を表す
+
:Group|正規表現の個々のグループにマッチした箇所を表す
+
:Capture|正規表現の部分式にマッチした箇所を表す
+

                  
+
例えばWindows形式のフルパスにマッチする正規表現"([A-Z]:)(\\[^\\ ]+)+"では、各クラスが表す部分文字列は次のようになります。
+
:Match|''([A-Z]:)(\\[^\\ ]+)+''の全体にマッチした箇所
+
:Group|''([A-Z]:)'' と ''(\\[^\\ ]+)+'' のグループそれぞれにマッチした箇所
+
:Capture|''[A-Z]:'' と ''\\[^\\ ]+'' の部分式それぞれにマッチした箇所
+

                  
+
入力文字列"xcopy C:\test D:\target\backup\files"を例にとると、上記の正規表現は"C:\test"と"D:\target\backup\files"の部分がマッチします。 このときにMatchクラスが表す箇所とインデックスは次のようになります。
+
 x c o p y   C : \ t e s t   D : \ t a r g e t \ b a c k u p \ f i l e s
+
             |           |   |                                         |
+
             `-----0-----'   `--------------------1--------------------'
+

                  
+
同様に、各Matchクラスの&msdn(netfx,member,System.Text.RegularExpressions.Match.Groups){Groupsプロパティ};に含まれるGroupが表す箇所とインデックスは次のようになります。 インデックスが0のグループはマッチした箇所全体を表す点に注意してください。
+
             |<-Match[0]>|   |<----------------Match[1]--------------->|
+
             |           |   |                                         |
+
 x c o p y   C : \ t e s t   D : \ t a r g e t \ b a c k u p \ f i l e s
+
             | | |       |   | | |                                     |
+
             `1' `---2---'   `1' `-----------------2-------------------'
+
             |           |   |                                         |
+
             `-----0-----'   `--------------------0--------------------'
+

                  
+
最後に、各Groupクラスの&msdn(netfx,member,System.Text.RegularExpressions.Group.Captures){Capturesプロパティ};に含まれるCaptureが表す箇所とインデックスは次のようになります。
+
           Group[1]        Group[1]
+
             | |             | |
+
             | | |Group[2]   | | |<-------------Group[2]-------------->|
+
             | | |       |   | | |                                     |
+
 x c o p y   C : \ t e s t   D : \ t a r g e t \ b a c k u p \ f i l e s
+
             | | |       |   | | |           | |           | |         |
+
             `0' `---0---'   `0' `-----0-----' `-----1-----' `----2----'
+

                  
+

                  
+
この例でのMatch・Group・Captureをツリー形式で表すと次のようになります。 Groupが複数のCaptureを含む場合、Group.Valueは一番最後のCaptureのValueとなる点に注意してください。
+

                  
+
#prompt{{
+
Regex: ([A-Z]:)(\\[^\\ ]+)+
+
Input: xcopy C:\test D:\target\backup\files
+

                  
+
Match[0]         C:\test                   (6+7)
+
  Group[0]       C:\test                   (6+7)
+
    Capture[0]   C:\test                   (6+7)
+
  Group[1]       C:                        (6+2)
+
    Capture[0]   C:                        (6+2)
+
  Group[2]       \test                     (8+5)
+
    Capture[0]   \test                     (8+5)
+

                  
+
Match[1]         D:\target\backup\files    (14+22)
+
  Group[0]       D:\target\backup\files    (14+22)
+
    Capture[0]   D:\target\backup\files    (14+22)
+
  Group[1]       D:                        (14+2)
+
    Capture[0]   D:                        (14+2)
+
  Group[2]       \files                    (30+6)
+
    Capture[0]   \target                   (16+7)
+
    Capture[1]   \backup                   (23+7)
+
    Capture[2]   \files                    (30+6)
+

                  
+
}}
+

                  
+
#code(cs,上記の結果を生成するコード){{
+
using System;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = @"xcopy C:\test D:\target\backup\files";
+
    string pattern = @"([A-Z]:)(\\[^\\ ]+)+";
+

                  
+
    Console.WriteLine("Regex: {0}", pattern);
+
    Console.WriteLine("Input: {0}", text);
+

                  
+
    Console.WriteLine();
+

                  
+
    PrintMatch(Regex.Matches(text, pattern));
+
  }
+

                  
+
  static void PrintMatch(MatchCollection matches)
+
  {
+
    for (int i = 0; i < matches.Count; i++)
+
    {
+
      Match m = matches[i];
+

                  
+
      Console.WriteLine("Match[{0}]         {1,-25} ({2}+{3})", i, m.Value, m.Index, m.Length);
+

                  
+
      PrintGroup(m.Groups);
+

                  
+
      Console.WriteLine();
+
    }
+
  }
+

                  
+
  static void PrintGroup(GroupCollection groups)
+
  {
+
    for (int i = 0; i < groups.Count; i++)
+
    {
+
      Group g = groups[i];
+

                  
+
      Console.WriteLine("  Group[{0}]       {1,-25} ({2}+{3})", i, g.Value, g.Index, g.Length);
+

                  
+
      PrintCapture(g.Captures);
+
    }
+
  }
+

                  
+
  static void PrintCapture(CaptureCollection captures)
+
  {
+
    for (int i = 0; i < captures.Count; i++)
+
    {
+
      Capture c = captures[i];
+

                  
+
      Console.WriteLine("    Capture[{0}]   {1,-25} ({2}+{3})", i, c.Value, c.Index, c.Length);
+
    }
+
  }
 
}
}
 
}}
}}
 

                

                
~
なお、これらのクラスは次のような継承関係となっています。 そのため、Value、Index、LengthなどのプロパティはCaptureクラスから継承されます。
**Matchesメソッド
~

                  
Matchesメソッドを使ってCSVの各レコードからフィールドの値を抽出する例。
+
-Captureクラス
+
--Groupクラス
+
---Matchクラス
+

                  
+
また、それぞれのクラス・プロパティ・対応するコレクションクラスの関係は次のようになっています。
+

                  
+
-Matchクラス - &msdn(netfx,type,System.Text.RegularExpressions.MatchCollection){MatchCollectionクラス};
+
-Groupクラス - &msdn(netfx,member,System.Text.RegularExpressions.Match.Groups){Match.Groupsプロパティ}; - &msdn(netfx,type,System.Text.RegularExpressions.GroupCollection){GroupCollectionクラス};
+
-Captureクラス - &msdn(netfx,member,System.Text.RegularExpressions.Group.Captures){Group.Capturesプロパティ}; - &msdn(netfx,type,System.Text.RegularExpressions.CaptureCollection){CaptureCollectionクラス};
+

                  
+
**グループとキャプチャを使った例
+
以下の例では、名前付きグループとMatchメソッドを使ってCSVの各レコードからフィールドの値を抽出し、表形式に整形しています。 この例で使用する正規表現は複雑になるため、構成要素毎に分けた正規表現を組み立てています。 それぞれの正規表現は次のようになっています。
+

                  
+
:recordPattern = ''^'''fieldPattern'''(,'''fieldPattern''')*$''|レコード(1行分)のパターン
+
行頭(''^'')に'''fieldPattern'''があり、カンマと'''fieldPattern'''の組み合わせ(''(,'''fieldPattern''')'')が0個以上続く(''*'')文字列で構成される
+
:fieldPattern = ''('''quotedFieldPattern'''|'''plainFieldPattern''')''|レコード内の各フィールドのパターン
+
クオートされたフィールド'''quotedFieldPattern'''、もしくはクオートされていないフィールド'''plainFieldPattern'''で構成される
+
:quotedFieldPattern = ''"(?<value>(""|[^"])*?)"''|クオートされているフィールドのパターン
+
開きの二重引用符(''"'')、クオートされた値(''(?<value>...)''の部分)、閉じの二重引用符(''"'')で構成される
+
クオートされた値は、エスケープされた二重引用符(''""'')または閉じの二重引用符以外の文字(''[^"]'')が0個以上続く(''*?'')文字列で構成される
+
(ここでは ''(""|[^"])'' が閉じの二重引用符にマッチしないよう、''*'' ではなく最短一致の ''*?'' を使用する)
+
:plainFieldPattern = ''(?<value>[^,]*)''|クオートされていないフィールドのパターン
+
カンマ以外の文字(''[^,]'')が0個以上続く(''*'')文字列で構成される
+

                  
+
なお、最終的に組み立てられた正規表現は実行結果として出力しています。 また、この例で使用している正規表現では、名前付きグループ'''value'''に複数のフィールドがキャプチャされるため、Group.Capturesプロパティを参照してキャプチャしたフィールドの値を列挙しています。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var inputs = new[] {
~
using System.Text.RegularExpressions;
  "column1,,column3",
-
  "column1,column2,column3,,",
-
  "\"column1\",\"column\"\"2\"\"\",column3",
-
};
 

                

                
~
class Sample
var quoted = "\"(?<value>(\"\"|\\w)*?)\"";
~
{
var plain = "(?<value>\\w*)";
~
  static void Main()
var field = string.Format("({0}|{1})", quoted, plain);
~
  {
var record = string.Format("^{0}(,{0})*$", field);
+
    string plainFieldPattern  = "(?<value>[^,]*)";
+
    string quotedFieldPattern = "\"(?<value>(\"\"|[^\"])*?)\"";
+
    string fieldPattern       = string.Format("({0}|{1})", quotedFieldPattern, plainFieldPattern);
+
    string recordPattern      = string.Format("^{0}(,{0})*$", fieldPattern);
+

                  
+
    Console.WriteLine(recordPattern);
+
    Console.WriteLine();
+

                  
+
    string[] records = new string[] {
+
      "type,example,max value",
+
      "",
+
      "int,\"0, 16, 42\",int.MaxValue",
+
      "double,3.14,double.MaxValue",
+
      "bool,\"true, false\",",
+
      "string,\"\"\"foo\"\", \"\"bar\"\"\",",
+
    };
+

                  
+
    foreach (string record in records)
+
    {
+
      Console.WriteLine("<{0}>", record);
+
    }
+

                  
+
    Console.WriteLine();
 

                

                
~
    foreach (string record in records)
foreach (var input in inputs) {
~
    {
  Console.WriteLine(input);
~
      Match m = Regex.Match(record, recordPattern);
  foreach (Match m in Regex.Matches(input, record)) {
~

                  
    foreach (Capture c in m.Groups["value"].Captures) {
~
      if (m.Success)
      Console.WriteLine("  {0}", c.Value);
+
      {
+
        foreach (Capture c in m.Groups["value"].Captures)
+
        {
+
          Console.Write("|{0,-20}", c.Value.Replace("\"\"", "\""));
+
        }
+
      }
+

                  
+
      Console.WriteLine();
 
    }
    }
 
  }
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim plainFieldPattern As String   = "(?<value>[^,]*)"
+
    Dim quotedFieldPattern As String  = """(?<value>(""""|[^""])*?)"""
+
    Dim fieldPattern As String        = String.Format("({0}|{1})", quotedFieldPattern, plainFieldPattern)
+
    Dim recordPattern As String       = String.Format("^{0}(,{0})*$", fieldPattern)
+

                  
+
    Console.WriteLine(recordPattern)
+
    Console.WriteLine()
+

                  
+
    Dim records() As String = New String() { _
+
      "type,example,max value", _
+
      "", _
+
      "int,""0, 16, 42"",int.MaxValue", _
+
      "double,3.14,double.MaxValue", _
+
      "bool,""true, false"",", _
+
      "string,""""""foo"""", """"bar""""""," _
+
    }
 

                

                
~
    For Each record As String In records
#prompt(実行結果){{
~
      Console.WriteLine("<{0}>", record)
column1,,column3
~
    Next
  column1
~

                  
  
~
    Console.WriteLine()
  column3
~

                  
column1,column2,column3,,
~
    For Each record As String In records
  column1
~
      Dim m As Match = Regex.Match(record, recordPattern)
  column2
~

                  
  column3
~
      If m.Success Then
  
~
        For Each c As Capture In m.Groups("value").Captures
  
~
          Console.Write("|{0,-20}", c.Value.Replace("""""", """"))
"column1","column""2""",column3
~
        Next
  column1
~
      End If
  column""2""
~

                  
  column3
+
      Console.WriteLine()
+
    Next
+
  End Sub
+
End Class
 
}}
}}
+
#tabpage-end
 

                

                
~
#prompt{{
**Replaceメソッド
~
^("(?<value>(""|[^"])*?)"|(?<value>[^,]*))(,("(?<value>(""|[^"])*?)"|(?<value>[^,]*)))*$
Replaceメソッドを使って単語の1文字目を大文字にする例。
+

                  
+
<type,example,max value>
+
<>
+
<int,"0, 16, 42",int.MaxValue>
+
<double,3.14,double.MaxValue>
+
<bool,"true, false",>
+
<string,"""foo"", ""bar""",>
+

                  
+
|type                |example             |max value           
+
|                    
+
|int                 |0, 16, 42           |int.MaxValue        
+
|double              |3.14                |double.MaxValue     
+
|bool                |true, false         |                    
+
|string              |"foo", "bar"        |                    
+
}}
+

                  
+
次の例では、名前付きグループとReplaceメソッドを使って単語の1文字目を大文字にしています。 この例で使用している正規表現では、最初の文字 ''\w'' をグループ名'''initial'''、後続する0文字以上の文字 ''\w*'' をグループ名'''trail''' としてキャプチャしています。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "The quick brown fox jumps over the lazy dog";
~
using System.Text.RegularExpressions;
var word = @"(?<initial>\w)(?<trail>\w*)";
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog";
+
    string pattern = @"(?<initial>\w)(?<trail>\w*)";
+

                  
+
    Console.WriteLine(text);
+
    Console.WriteLine(Regex.Replace(text, pattern, ReplaceInitialToUpper));
+
  }
 

                

                
~
  static string ReplaceInitialToUpper(Match m)
Console.WriteLine(input);
~
  {
Console.WriteLine(Regex.Replace(input, word, delegate(Match m) {
~
    return m.Groups["initial"].Value.ToUpper() + m.Groups["trail"].Value;
  return m.Groups["initial"].Value.ToUpper() + m.Groups["trail"].Value;
~
  }
}));
+
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+
    Dim pattern As String = "(?<initial>\w)(?<trail>\w*)"
+

                  
+
    Console.WriteLine(text)
+
    Console.WriteLine(Regex.Replace(text, pattern, AddressOf ReplaceInitialToUpper))
+
  End Sub
+

                  
+
  Shared Function ReplaceInitialToUpper(ByVal m As Match) As String
+
    Return m.Groups("initial").Value.ToUpper() + m.Groups("trail").Value
+
  End Function
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
#prompt(実行結果){{
 
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
 
The Quick Brown Fox Jumps Over The Lazy Dog
The Quick Brown Fox Jumps Over The Lazy Dog
 
}}
}}
 

                

                
~
なお、上記の例での正規表現は、''\b'' を使うことで後続する文字のキャプチャを省略し、正規表現と置換の処理を次のように簡略化することが出来ます。
上記の例を、\bを使ってより簡略に書き換えた例。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "The quick brown fox jumps over the lazy dog";
~
using System.Text.RegularExpressions;
var initial = @"\b(?<initial>\w)";
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog";
+
    string pattern = @"\b(?<initial>\w)";
 

                

                
~
    Console.WriteLine(text);
Console.WriteLine(input);
~
    Console.WriteLine(Regex.Replace(text, pattern, ReplaceInitialToUpper));
Console.WriteLine(Regex.Replace(input, initial, delegate(Match m) {
~
  }
  return m.Groups["initial"].Value.ToUpper();
~

                  
}));
+
  static string ReplaceInitialToUpper(Match m)
+
  {
+
    return m.Groups["initial"].Value.ToUpper();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+
    Dim pattern As String = "\b(?<initial>\w)"
+

                  
+
    Console.WriteLine(text)
+
    Console.WriteLine(Regex.Replace(text, pattern, AddressOf ReplaceInitialToUpper))
+
  End Sub
+

                  
+
  Shared Function ReplaceInitialToUpper(ByVal m As Match) As String
+
    Return m.Groups("initial").Value.ToUpper()
+
  End Function
+
End Class
 
}}
}}
+
#tabpage-end
 

                

                
~
さらに、''\b'' は幅を持たない(ゼロ幅の)正規表現要素であり、マッチした文字列中には現れないためグループを参照せずに次のようにすることも可能です。
\bはゼロ幅であり部分文字列中には現れないため、さらに簡略化して次のようにも書ける。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "The quick brown fox jumps over the lazy dog";
~
using System.Text.RegularExpressions;
var initial = @"\b\w";
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "The quick brown fox jumps over the lazy dog";
+
    string pattern = @"\b(?<initial>\w)";
+

                  
+
    Console.WriteLine(text);
+
    Console.WriteLine(Regex.Replace(text, pattern, ReplaceInitialToUpper));
+
  }
 

                

                
~
  static string ReplaceInitialToUpper(Match m)
Console.WriteLine(input);
~
  {
Console.WriteLine(Regex.Replace(input, initial, delegate(Match m) {
~
    return m.Value.ToUpper();
  return m.Value.ToUpper();
~
  }
}));
+
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "The quick brown fox jumps over the lazy dog"
+
    Dim pattern As String = "\b(?<initial>\w)"
+

                  
+
    Console.WriteLine(text)
+
    Console.WriteLine(Regex.Replace(text, pattern, AddressOf ReplaceInitialToUpper))
+
  End Sub
+

                  
+
  Shared Function ReplaceInitialToUpper(ByVal m As Match) As String
+
    Return m.Value.ToUpper()
+
  End Function
+
End Class
+
}}
+
#tabpage-end
+

                  
+
*&aname(RegexOptions){RegexOptions列挙体};
+
&msdn(netfx,type,System.Text.RegularExpressions.RegexOptions){RegexOptions列挙体};でオプションを指定することで、正規表現のマッチングの動作を変更することが出来ます。 指定できるオプションには次のようなものがあります。 なお、一部のオプションは正規表現文字列内でインラインオプションとして指定することができ、動作を一時的に変更することが出来ます。
 

                

                
~
|*RegexOptionsで指定できる値
**Splitメソッド
~
|~値|~動作|~備考|h
Splitメソッドを用いて、改行文字に\rと\nが混在するテキストを行毎に分割する例。 この例では\r, \n, \r\nのいずれかを改行と見なす。
+
|~None|なし。 デフォルトの動作。||
+
|~IgnoreCase|{{
+
大文字小文字の違いを無視する。
+
}}|インラインオプションでは ''(?i:'''subexpression''')''|
+
|~Multiline|{{
+
複数行モードにする。
+
''^'' は文字列の先頭に加え行頭にもマッチ、''$'' は文字列の末尾に加え行末にもマッチするようになる。
+
}}|インラインオプションでは ''(?m:'''subexpression''')''|
+
|~Singleline|{{
+
単一行モードにする。
+
''.'' が ''\n''にもマッチするようになる。
+
}}|インラインオプションでは ''(?s:'''subexpression''')''|
+
|~ExplicitCapture|{{
+
明示的に名前または番号を指定したグループのみをキャプチャする。
+
通常のグループ ''('''subexpression''')'' はキャプチャされないグループ ''(?:'''subexpression''')'' と同様に扱われる。
+
}}|インラインオプションでは ''(?n:'''subexpression''')''|
+
|~IgnorePatternWhitespace|{{
+
エスケープされない空白をパターンから除外し、#以降を行末までのコメントとして扱うように変更する。
+
}}|インラインオプションでは ''(?x:'''subexpression''')''|
+
|~CultureInvariant|{{
+
インバリアントカルチャを使った比較を行う。
+
(デフォルトではThread.CurrenThread.CurrentCultureに指定されているカルチャに従って比較が行われる)
+
}}|関連:[[programming/netfx/locale/0_abstract]], [[programming/netfx/string/2_comparison]]|
+
|~RightToLeft|{{
+
検索の方向を右から左にする。
+
キャプチャされるグループに割り当てられるインデックスも逆になる。
+
}}||
+
|~Compiled|使用される前に正規表現をコンパイルし、ILコードを生成する。|[[詳細は後述>#compiled_regex]]|
+
|~ECMAScript|{{
+
ECMAScript互換の動作にする。
+
''\w'' は ''[a-zA-Z0-9_]''、''\d'' は ''[0-9]''と等価になるなど、いくつかの正規表現要素の意味が変わる。
+
}}|IgnoreCase、Multiline、Compiledと組み合わせて使用する必要ある。|
+

                  
+
**Multilineを使った例
+
次の例では、正規表現要素 ''^'' を使って行頭の空白(半角全角空白、タブを含む)を除去しています。 RegexOptions.Multilineを指定しない場合、''^'' は文字列の先頭のみにマッチするため、意図した動作とはなりません。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "line1\r\nline2\nline3\rline4\n\rline6";
~
using System.Text.RegularExpressions;
var newline = @"\r\n|\r|\n";
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "    1行目\n\t2行目\n \t 3行目\n 4行目";
+
    string pattern = @"^\s*"; // @"(?m:^\s*)"
+

                  
+
    Console.WriteLine("[input]");
+
    Console.WriteLine(text);
 

                

                
~
    Console.WriteLine("[Regex.Replace(RegexOptions.Multiline)]");
foreach (var line in Regex.Split(input, newline)) {
~
    Console.WriteLine(Regex.Replace(text, pattern, string.Empty, RegexOptions.Multiline));
  Console.WriteLine("[{0}]", line);
+

                  
+
    Console.WriteLine("[Regex.Replace(RegexOptions.None)]");
+
    Console.WriteLine(Regex.Replace(text, pattern, string.Empty));
+
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "    1行目" + vbLf + vbTab + "2行目" + vbLf + " " + vbTab + " 3行目" + vbLf + " 4行目"
+
    Dim pattern As String = "^\s*" ' "(?m:^\s*)"
+

                  
+
    Console.WriteLine("[input]")
+
    Console.WriteLine(text)
+

                  
+
    Console.WriteLine("[Regex.Replace(RegexOptions.Multiline)]")
+
    Console.WriteLine(Regex.Replace(text, pattern, String.Empty, RegexOptions.Multiline))
+

                  
+
    Console.WriteLine("[Regex.Replace(RegexOptions.None)]")
+
    Console.WriteLine(Regex.Replace(text, pattern, String.Empty))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
 

                

                
~
#prompt{{
#prompt(実行結果){{
~
[input]
[line1]
~
    1行目
[line2]
~
	2行目
[line3]
~
 	 3行目
[line4]
~
 4行目
[]
~
[Regex.Replace(RegexOptions.Multiline)]
[line6]
+
1行目
+
2行目
+
3行目
+
4行目
+
[Regex.Replace(RegexOptions.None)]
+
1行目
+
	2行目
+
 	 3行目
+
 4行目
 
}}
}}
 

                

                
~
コメントアウトしてある正規表現は、インラインオプションとして指定しているものです。 これを使用した場合は、RegexOptionsの指定に関わらず意図した結果が得られます。
Splitメソッドに指定される正規表現にキャプチャされるグループを含む場合は、グループの部分文字列も戻り値に含まれる。 そのため、次の例
+

                  
+
**ExplicitCaptureを使った例
+
次の例では、正規表現を使って行の分割と改行前後の空白の除去を同時に行っています。 改行文字の指定に正規表現"(\r\n|\r|\n)"を使っています。 Splitメソッドでは正規表現にグループを含む場合は、グループにマッチする部分文字列も戻り値に含まれます。 そのため、RegexOptions.ExplicitCaptureを指定しない場合、意図した動作とはなりません。
+

                  
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
var input = "line1\r\nline2\nline3\rline4\n\rline6";
~
using System.Text.RegularExpressions;
var newline = @"(\r\n|\r|\n)";
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "1行目    \r\n\t2行目  \n \t 3行目\t\r 4行目";
+
    string pattern = @"\s*(\r\n|\r|\n)\s*"; // @"\s*(?x:\r\n|\r|\n)\s*"
+

                  
+
    Console.WriteLine("[input]");
+
    Console.WriteLine("<{0}>", Escape(text));
+

                  
+
    Console.WriteLine("[Regex.Split(RegexOptions.ExplicitCapture)]");
+

                  
+
    foreach (string line in Regex.Split(text, pattern, RegexOptions.ExplicitCapture))
+
    {
+
      Console.WriteLine("<{0}>", Escape(line));
+
    }
+

                  
+
    Console.WriteLine("[Regex.Split(RegexOptions.None)]");
+

                  
+
    foreach (string line in Regex.Split(text, pattern))
+
    {
+
      Console.WriteLine("<{0}>", Escape(line));
+
    }
+
  }
+

                  
+
  static string Escape(string s)
+
  {
+
    return s.Replace("\n", @"\n").Replace("\r", @"\r");
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "1行目    " + vbCrLf + vbTab + "2行目  " + vbLf + " " + vbTab + " 3行目" + vbTab + vbCr + " 4行目"
+
    Dim pattern As String = "\s*(\r\n|\r|\n)\s*" ' "\s*(?x:\r\n|\r|\n)\s*"
+

                  
+
    Console.WriteLine("[input]")
+
    Console.WriteLine("<{0}>", Escape(text))
+

                  
+
    Console.WriteLine("[Regex.Split(RegexOptions.ExplicitCapture)]")
+

                  
+
    For Each line As String In Regex.Split(text, pattern, RegexOptions.ExplicitCapture)
+
      Console.WriteLine("<{0}>", Escape(line))
+
    Next
+

                  
+
    Console.WriteLine("[Regex.Split(RegexOptions.None)]")
+

                  
+
    For Each line As String In Regex.Split(text, pattern)
+
      Console.WriteLine("<{0}>", Escape(line))
+
    Next
+
  End Sub
+

                  
+
  Shared Function Escape(ByVal s As String) As String
+
    Return s.Replace(vbLf, "\n").Replace(vbCr, "\r")
+
  End Function
+
End Class
+
}}
+
#tabpage-end
+

                  
+
#prompt{{
+
[input]
+
<1行目    \r\n	2行目  \n 	 3行目	\r 4行目>
+
[Regex.Split(RegexOptions.ExplicitCapture)]
+
<1行目>
+
<2行目>
+
<3行目>
+
<4行目>
+
[Regex.Split(RegexOptions.None)]
+
<1行目>
+
<\n>
+
<2行目>
+
<\n>
+
<3行目>
+
<\r>
+
<4行目>
+
}}
+

                  
+
コメントアウトしてある正規表現は、インラインオプションとして指定しているものです。 これを使用した場合は、RegexOptionsの指定に関わらず意図した結果が得られます。
 

                

                
~
**CultureInvariantを使った例
foreach (var line in Regex.Split(input, newline)) {
~
次の例では、正規表現を使って単語がiで始まるかどうかを調べています。 比較の際、インラインオプション ''(?i:)'' により、大文字小文字の違いは無視されます。
  Console.WriteLine("[{0}]", line.Replace("\n", "\\n").Replace("\r", "\\r"));
+

                  
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Globalization;
+
using System.Text.RegularExpressions;
+
using System.Threading;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string text = "Internet";
+
    string pattern = @"(?i:i(\w+))";
+

                  
+
    Console.WriteLine(Thread.CurrentThread.CurrentCulture);
+
    Console.WriteLine(Regex.IsMatch(text, pattern));
+
    Console.WriteLine(Regex.IsMatch(text, pattern, RegexOptions.CultureInvariant));
+
    Console.WriteLine();
+

                  
+
    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR");
+

                  
+
    Console.WriteLine(Thread.CurrentThread.CurrentCulture);
+
    Console.WriteLine(Regex.IsMatch(text, pattern));
+
    Console.WriteLine(Regex.IsMatch(text, pattern, RegexOptions.CultureInvariant));
+
    Console.WriteLine();
+
  }
 
}
}
 
}}
}}
~
#tabpage(VB)
を実行すると。
+
#code(vb){{
+
Imports System
+
Imports System.Globalization
+
Imports System.Text.RegularExpressions
+
Imports System.Threading
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim text As String = "Internet"
+
    Dim pattern As String = "(?i:i(\w+))"
+

                  
+
    Console.WriteLine(Thread.CurrentThread.CurrentCulture)
+
    Console.WriteLine(Regex.IsMatch(text, pattern))
+
    Console.WriteLine(Regex.IsMatch(text, pattern, RegexOptions.CultureInvariant))
+
    Console.WriteLine()
+

                  
+
    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR")
+

                  
+
    Console.WriteLine(Thread.CurrentThread.CurrentCulture)
+
    Console.WriteLine(Regex.IsMatch(text, pattern))
+
    Console.WriteLine(Regex.IsMatch(text, pattern, RegexOptions.CultureInvariant))
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
この例での入力文字列"Internet"はiで始まる単語のため、カルチャがja-JPの場合はRegexOptions.CultureInvariantを指定しているかどうかに関わらず正規表現にマッチします。 しかしカルチャをtr-TR(トルコ語/トルコ)に変更すると、RegexOptions.CultureInvariantを指定しないとマッチしません。
+

                  
+
#prompt{{
+
ja-JP
+
True
+
True
+

                  
+
tr-TR
+
False
+
True
+

                  
+
}}
+

                  
+
トルコ語ではiとIが大文字小文字の関係ではなく異なる文字として扱われるため、正規表現には一致しなくなります(参考、Internetのトルコ語表記: [[İnternet:http://tr.wikipedia.org/wiki/İnternet]])。 カルチャによって異なる結果とならないようにするには、RegexOptions.CultureInvariantを指定する必要があります。
+

                  
+
*正規表現のキャッシュとコンパイル
+
**&aname(cached_regex){正規表現のキャッシュ};
+
Regexクラスのインスタンスメソッドのクラスメソッドでは使い方には大きな違いはありませんが、内部で動作する正規表現の実行エンジンの挙動は異なります。 それに起因してパフォーマンスにも違いが現れます。
+

                  
+
.NET Frameworkの正規表現では、正規表現を使用する前に正規表現エンジンによりパターンの解析が行われます。 Regexクラスのインスタンスを作成する場合は、作成時に一度だけ解析が行われます。 クラスメソッドを使う場合でも同様にメソッドを呼び出す度に解析が行われますが、最近使用された正規表現はキャッシュされるため、同じパターンを使用する場合は解析は一度だけになります。 なお、キャッシュされる正規表現の個数はデフォルトでは15個となっていて、キャッシュの個数は&msdn(netfx,member,System.Text.RegularExpressions.Regex.CacheSize){Regex.CacheSizeプロパティ};で取得・設定することが出来ます。
+

                  
+
次の結果は、同じ正規表現を使い、クラスメソッドのIsMatchとインスタンスメソッドのIsMatchをそれぞれ5×100,000回呼び出した場合の経過時間を3回計測したものです。
+

                  
+
#prompt{{
+
Microsoft Windows NT 5.1.2600 Service Pack 3
+
2.0.50727.3615
+
Regex.CacheSize = 15
+
[0]
+
static:   00:00:00.9203100
+
instance: 00:00:00.5604796
+
[1]
+
static:   00:00:00.9829842
+
instance: 00:00:00.5675445
+
[2]
+
static:   00:00:00.9279713
+
instance: 00:00:00.5522659
+
}}
+

                  
+
クラスメソッドの方が若干時間がかかっていますが、これはキャッシュの有無チェックや内部で使用するインスタンスの生成などによる差と思われます。
+

                  
+
続いて、Regex.CacheSizeに0を指定してキャッシュを無効した場合の結果を見てみます。 クラスメソッドの呼び出しの度にパターンの解析が行われるようになるため、処理時間が大幅に増えます。
+

                  
+
#prompt{{
+
Microsoft Windows NT 5.1.2600 Service Pack 3
+
2.0.50727.3615
+
Regex.CacheSize = 0
+
[0]
+
static:   00:00:06.7950112
+
instance: 00:00:00.5796448
+
[1]
+
static:   00:00:06.6722204
+
instance: 00:00:00.5643808
+
[2]
+
static:   00:00:06.9712903
+
instance: 00:00:00.5722832
+
}}
+

                  
+
これらのことから次のようなことが言えると思います。
+
+同じ正規表現を何度も使う場合はクラスメソッドではなくインスタンスを作成して使用することで処理時間を改善できる
+
+クラスメソッドを使っている状況では、
+
++使用頻度が高く、かつ同じ正規表現を多く使っている場合は、Regex.CacheSizeを大きくすることで処理時間を改善できる
+
++逆に、使用頻度が低いものや、複雑な正規表現を多数使っている場合は、Regex.CacheSizeを小さく(もしくは0にして無効にする)ことで使用するメモリの量を減らすことが出来る
+

                  
+
なお、計測に使用したコードは次のとおりです。
+

                  
+
#code(cs){{
+
using System;
+
using System.Diagnostics;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      @"xcopy C:\test D:\target\backup\files",
+
      @"C:\Windows\Microsoft.NET\Framework\v3.5",
+
      @"http://example.com/",
+
      @"/usr/bin/mono",
+
      @"cd ..\..\backup\",
+
    };
+

                  
+
    const string pattern = @"([A-Z]:)(\\[^\\ ]+)+"; // 使用する正規表現のパターン
+
    const int repeat = 100 * 1000; // 繰り返しの回数
+

                  
+
    Console.WriteLine(Environment.OSVersion);
+
    Console.WriteLine(Environment.Version);
+

                  
+
    // Regex.CacheSize = 0;
+
    Console.WriteLine("Regex.CacheSize = {0}", Regex.CacheSize);
+

                  
+
    for (int t = 0; t < 3; t++)
+
    {
+
      // クラスメソッドを使った場合の経過時間を計測
+
      Stopwatch sw1 = Stopwatch.StartNew();
+

                  
+
      for (int i = 0; i < repeat; i++)
+
      {
+
        foreach (string file in files)
+
        {
+
          Regex.IsMatch(file, pattern);
+
        }
+
      }
+

                  
+
      sw1.Stop();
+

                  
+
      // インスタンスメソッドを使った場合の経過時間(インスタンス生成時間を含む)を計測
+
      Stopwatch sw2 = Stopwatch.StartNew();
+

                  
+
      Regex regex = new Regex(pattern);
+

                  
+
      for (int i = 0; i < repeat; i++)
+
      {
+
        foreach (string file in files)
+
        {
+
          regex.IsMatch(file);
+
        }
+
      }
+

                  
+
      sw2.Stop();
+

                  
+
      Console.WriteLine("[{0}]", t);
+
      Console.WriteLine("static:   {0}", sw1.Elapsed);
+
      Console.WriteLine("instance: {0}", sw2.Elapsed);
+
    }
+
  }
+
}
+
}}
+

                  
+
参考までに、Mono 2.8.1の時点では正規表現のキャッシュは実装されていないようで、Regex.CacheSizeの値を変更しても処理時間はほとんど変わりません。
+

                  
+
#prompt{{
+
Unix 2.6.32.25
+
2.0.50727.1433
+
Regex.CacheSize = 15
+
[0]
+
static:   00:00:01.9511728
+
instance: 00:00:01.5228759
+
[1]
+
static:   00:00:01.8617440
+
instance: 00:00:01.4998760
+
[2]
+
static:   00:00:01.9853304
+
instance: 00:00:01.4868364
+

                  
+

                  
+

                  
+
Unix 2.6.32.25
+
2.0.50727.1433
+
Regex.CacheSize = 0
+
[0]
+
static:   00:00:01.9619754
+
instance: 00:00:01.5278862
+
[1]
+
static:   00:00:01.8375399
+
instance: 00:00:01.4873681
+
[2]
+
static:   00:00:01.8235452
+
instance: 00:00:01.4647317
+

                  
+
}}
+

                  
+
**&aname(compiled_regex){正規表現のコンパイル}; (RegexOptions.Compiled)
+
RegexOptions.Compiledを指定すると、正規表現が使用される前にパターンの解析・コンパイルとILコードの生成が行われるようになります。 これにより、最初に正規表現を使用する際はコンパイルを行う分の時間はかかりますが、以降はILコードに変換されたものを使うようになるので実行速度が向上します。
+

                  
+
次の結果は、同じ正規表現を使い、RegexOptions.Compiledを指定したインスタンスとそうでないインスタンスの二つを作成し、それぞれのインスタンスのIsMatchを5×100,000回呼び出した場合の経過時間を3回計測したものです。
+

                  
+
#prompt{{
+
[0]
+
default:  00:00:00.5575484
+
compiled: 00:00:00.3660707
+
[1]
+
default:  00:00:00.6100348
+
compiled: 00:00:00.3872334
+
[2]
+
default:  00:00:00.5817512
+
compiled: 00:00:00.3733582
+
}}
+

                  
+
この結果から分かるとおり、RegexOptions.Compiledを指定した方が指定しなかった場合と比べて処理時間が短くなっています。 正規表現の複雑さや使用頻度にもよりますが、RegexOptions.Compiledを指定することで処理時間の改善が期待できます。
+

                  
+
なお、計測に使用したコードは次のとおりです。
+

                  
+
#code(cs){{
+
using System;
+
using System.Diagnostics;
+
using System.Text.RegularExpressions;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      @"xcopy C:\test D:\target\backup\files",
+
      @"C:\Windows\Microsoft.NET\Framework\v3.5",
+
      @"http://example.com/",
+
      @"/usr/bin/mono",
+
      @"cd ..\..\backup\",
+
    };
+

                  
+
    const string pattern = @"([A-Z]:)(\\[^\\ ]+)+"; // 使用する正規表現のパターン
+
    const int repeat = 100 * 1000; // 繰り返しの回数
+

                  
+
    Console.WriteLine(Environment.OSVersion);
+
    Console.WriteLine(Environment.Version);
+

                  
+
    for (int t = 0; t < 3; t++)
+
    {
+
      // オプションを指定していないインスタンスを使った場合の経過時間(インスタンス生成時間を含む)を計測
+
      Stopwatch sw1 = Stopwatch.StartNew();
+

                  
+
      Regex regexDefault = new Regex(pattern);
+

                  
+
      for (int i = 0; i < repeat; i++)
+
      {
+
        foreach (string file in files)
+
        {
+
          regexDefault.IsMatch(file);
+
        }
+
      }
+

                  
+
      sw1.Stop();
+

                  
+
      // RegexOptions.Compiledを指定したインスタンスを使った場合の経過時間(インスタンス生成時間を含む)を計測
+
      Stopwatch sw2 = Stopwatch.StartNew();
+

                  
+
      Regex regexCompiled = new Regex(pattern, RegexOptions.Compiled);
+

                  
+
      for (int i = 0; i < repeat; i++)
+
      {
+
        foreach (string file in files)
+
        {
+
          regexCompiled.IsMatch(file);
+
        }
+
      }
+

                  
+
      sw2.Stop();
+

                  
+
      Console.WriteLine("[{0}]", t);
+
      Console.WriteLine("default:  {0}", sw1.Elapsed);
+
      Console.WriteLine("compiled: {0}", sw2.Elapsed);
+
    }
+
  }
+
}
+
}}
+

                  
+
参考までに、Mono 2.8.1の時点では正規表現のコンパイルは実装されていないようで、RegexOptions.Compiled.CacheSizeを指定しても実行速度はほとんど変わりません。
+

                  
+
#prompt{{
+
Unix 2.6.32.25
+
2.0.50727.1433
+
[0]
+
default:  00:00:01.5728772
+
compiled: 00:00:01.5484837
+
[1]
+
default:  00:00:01.5269132
+
compiled: 00:00:01.5245756
+
[2]
+
default:  00:00:01.5262093
+
compiled: 00:00:01.5245357
+
}}
+

                  
+
**正規表現のプリコンパイル (Regex.CompileToAssembly)
+
&msdn(netfx,type,System.Text.RegularExpressions.Regex.CompileToAssembly){Regex.CompileToAssemblyメソッド};と&msdn(netfx,type,System.Text.RegularExpressions.RegexCompilationInfo){RegexCompilationInfoクラス};を使用すると、正規表現をコンパイルしてILコードに変換し、それらをまとめてアセンブリを生成することが出来ます。 これにより、プリコンパイルされた正規表現を使用することが出来るようになります。 RegexOptions.Compiledでは実行時にコンパイルされるのに対し、Regex.CompileToAssemblyで生成したアセンブリを使用すれば既にコンパイル済みの正規表現を使用することになるため、実行時のコンパイル時間を削減することが出来ます。
+

                  
+
次のコードでは、Regex.CompileToAssemblyを使って正規表現をコンパイルし、アセンブリを生成しています。
+

                  
+
#tabpage(C#)
+
#code(cs,compile.cs){{
+
// csc compile.cs
+
// compile.exe
+

                  
+
using System;
+
using System.Text.RegularExpressions;
+
using System.Reflection;
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    const string pattern = @"([A-Z]:)(\\[^\\ ]+)+";
+

                  
+
    // コンパイルする正規表現に関する情報を作成
+
    RegexCompilationInfo rci = new RegexCompilationInfo(pattern,                // コンパイルする正規表現
+
                                                        RegexOptions.None,
+
                                                        "WindowsFullPathRegex", // コンパイル後の正規表現のクラス名
+
                                                        "RegexLibrary",         // コンパイル後のクラスの名前空間
+
                                                        true);                  // クラスをpublicにする
+

                  
+
    // 生成されるアセンブリのAssemblyName
+
    AssemblyName assmName = new AssemblyName("RegexLibrary");
+

                  
+
    // コンパイルしてアセンブリを生成する
+
    Regex.CompileToAssembly(new RegexCompilationInfo[] {rci}, assmName);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,compile.vb){{
+
' vbc compile.vb
+
' compile.exe
+

                  
+
Imports System
+
Imports System.Reflection
+
Imports System.Text.RegularExpressions
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Const pattern As String = "([A-Z]:)(\\[^\\ ]+)+"
+

                  
+
    ' コンパイルする正規表現に関する情報を作成
+
    Dim rci As New RegexCompilationInfo(pattern, _
+
                                        RegexOptions.None, _
+
                                        "WindowsFullPathRegex", _
+
                                        "RegexLibrary", _
+
                                        True)
+

                  
+
    ' 生成するアセンブリのAssemblyName
+
    Dim assmName As New AssemblyName("RegexLibrary")
+

                  
+
    ' コンパイルしてアセンブリを生成する
+
    Regex.CompileToAssembly(New RegexCompilationInfo() {rci}, assmName)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
このコードを実行すると、一つのクラスRegexLibrary.WindowsFullPathRegexが含まれるライブラリアセンブリRegexLibrary.dllが生成されます。
+

                  
+
続いて、生成されたアセンブリを参照して、テスト用のコードを実行してみます。 Regex.CompileToAssemblyで生成されるクラスはRegexクラスの派生クラスとなるため、Regexクラスのメソッドを使うことが出来ます。
+

                  
+
#tabpage(C#)
+
#code(cs,test.cs){{
+
// csc test.cs /r:RegexLibrary.dll
+
// test.exe
+

                  
+
using System;
+
using System.Text.RegularExpressions;
+
using RegexLibrary; // RegexCompilationInfoで指定した名前空間
+

                  
+
class Sample
+
{
+
  static void Main()
+
  {
+
    string[] files = new string[] {
+
      @"xcopy C:\test D:\target\backup\files",
+
      @"C:\Windows\Microsoft.NET\Framework\v3.5",
+
      @"http://example.com/",
+
      @"/usr/bin/mono",
+
      @"cd ..\..\backup\",
+
    };
+

                  
+
    Regex r = new WindowsFullPathRegex(); // RegexCompilationInfoで指定したクラス名
+

                  
+
    Console.WriteLine("pattern: {0}", r.ToString());
+

                  
+
    foreach (string file in files)
+
    {
+
      Console.Write("{0,-45} ", file);
+

                  
+
      if (r.IsMatch(file))
+
        Console.WriteLine("O");
+
      else
+
        Console.WriteLine("X");
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,test.vb){{
+
' vbc test.cs /r:RegexLibrary.dll
+
' test.exe
+

                  
+
Imports System
+
Imports System.Text.RegularExpressions
+
Imports RegexLibrary ' RegexCompilationInfoで指定した名前空間
+

                  
+
Class Sample
+
  Shared Sub Main()
+
    Dim files() As String = New String() { _
+
      "xcopy C:\test D:\target\backup\files", _
+
      "C:\Windows\Microsoft.NET\Framework\v3.5", _
+
      "http://example.com/", _
+
      "/usr/bin/mono", _
+
      "cd ..\..\backup\" _
+
    }
+

                  
+
    Dim r As Regex = New WindowsFullPathRegex() ' RegexCompilationInfoで指定したクラス名
+

                  
+
    Console.WriteLine("pattern: {0}", r.ToString())
+

                  
+
    For Each file As String In files
+
      Console.Write("{0,-45} ", file)
+

                  
+
      If r.IsMatch(file)
+
        Console.WriteLine("O")
+
      Else
+
        Console.WriteLine("X")
+
      End If
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

                  
+
このコードを実行すると、次のような結果が得られるはずです。
+

                  
+
#prompt{{
+
pattern: ([A-Z]:)(\\[^\\ ]+)+
+
xcopy C:\test D:\target\backup\files          O
+
C:\Windows\Microsoft.NET\Framework\v3.5       O
+
http://example.com/                           X
+
/usr/bin/mono                                 X
+
cd ..\..\backup\                              X
+
}}
+

                  
+
なお、Mono 2.8.1の時点ではRegex.CompileToAssemblyメソッドによるアセンブリの生成は実装されていません。
+

                  
+
#prompt{{
+
$ gmcs compile.cs && mono compile.exe
+

                  
+
Unhandled Exception: System.NotImplementedException: The requested feature is not implemented.
+
  at System.Text.RegularExpressions.Regex.CompileToAssembly (System.Text.RegularExpressions.RegexCompilationInfo[] regexes, System.Reflection.AssemblyName aname, System.Reflection.Emit.CustomAttributeBuilder[] attribs, System.String resourceFile) [0x00000] in <filename unknown>:0 
+
  at System.Text.RegularExpressions.Regex.CompileToAssembly (System.Text.RegularExpressions.RegexCompilationInfo[] regexes, System.Reflection.AssemblyName aname) [0x00000] in <filename unknown>:0 
+
  at Sample.Main () [0x00000] in <filename unknown>:0 
+
}}
+

                  
+
もちろん、.NET Framework上で生成したアセンブリを参照して使用することは出来ます。
 

                

                
 
#prompt{{
#prompt{{
~
$ gmcs test.cs /r:RegexLibrary.dll && mono test.exe
[line1]
~
pattern: ([A-Z]:)(\\[^\\ ]+)+
[\r\n]
~
xcopy C:\test D:\target\backup\files          O
[line2]
~
C:\Windows\Microsoft.NET\Framework\v3.5       O
[\n]
~
http://example.com/                           X
[line3]
~
/usr/bin/mono                                 X
[\r]
~
cd ..\..\backup\                              X
[line4]
-
[\n]
-
[]
-
[\r]
-
[line6]
 
}}
}}
-
となる。 グループを含む正規表現で区切り文字をキャプチャさせたくない場合は、xオプション(RegexOptions.ExplicitCapture)を指定するか、('''subexpression''')の代わりに(?:'''subexpression''')を用いる。
 

                

                
 
#navi(..)
#navi(..)
 

                

                

programming/netfx/regex/index.wiki.txt

current previous
3,6 3,12
 
${smdncms:keywords,正規表現,Regex,Regexp,System.Text.RegularExpressions}
${smdncms:keywords,正規表現,Regex,Regexp,System.Text.RegularExpressions}
 
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,.net framework}
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,.net framework}
 

                

                
-
(このドキュメントは再構成中です)
-

                  
-
正規表現とは、MS-DOSなどで用いられるワイルドカード文字(これはもちろんWindowsでも使われている)などのように、文字列の中から特定の「パターン」に一致する部分を検索したり、置き換えたりするためのものです。 正規表現という名称から、非常に難しい概念のように思われるかもしれませんが、実際にはワイルドカード同様簡単に理解できるものです。
-

                  
-
正規表現では、「あ行で始まる言葉」とか「途中に『こんにちは』が含まれる言葉」というような条件を記号的に表記します。 例えば「*.vb」というワイルドカードでは「.vbで終わる全てのファイル」、つまり「拡張子がvbである全てのファイル」という意味を表しますが、正規表現もこれと似たような表現をします。
-

                  
 
ここでは.NET Frameworkにおける正規表現と関連するクラスの使い方について解説します。
ここでは.NET Frameworkにおける正規表現と関連するクラスの使い方について解説します。
 

                

                
 
-ページ一覧
-ページ一覧