正規表現

正規表現に関連するクラス
クラス 用途
Regex 変更不可の正規表現
RegexCompilationInfo 正規表現をコンパイルしてアセンブリを作成するために使用する、正規表現についての情報
RegexRunner コンパイル済みの正規表現の基本クラス
(製品インフラストラクチャをサポートしており、コードから直接使用されることを想定していない)
RegexRunnerFactory コンパイルされた正規表現用の、RegexRunnerクラスを作成する
(製品インフラストラクチャをサポートしており、コードから直接使用されることを想定していない)
RegexMatchTimeoutException 正規表現パターン一致メソッドの実行時間が、そのタイムアウト間隔を超えるとスローされる例外
検索結果を表すクラス
クラス 用途
Match 単一の正規表現検索の結果
Group 単一のキャプチャ グループの結果
Capture 単一の部分式キャプチャの結果
MatchCollection 正規表現パターンを入力文字列に繰り返し適用したときにパターンに一致した、一連の対象
GroupCollection 1回の検索一致でキャプチャされた、グループのセット
CaptureCollection 1つのキャプチャ グループによって作成された、キャプチャのセット
System.Text.RegularExpressions 名前空間 | MSDN

Regexクラス

string text = "ab123cd99";
Regex regex = new Regex("[0-9]+");

Match match = regex.Match(text);
// match.value "123"

MatchCollection matches = regex.Matches(text);
// matches[0].Value "123"
// matches[1].Value "99"

string str = regex.Replace(text, "A");
// str "abAcdA"

if(regex.IsMatch(text))
{
    //
}

コンストラクタ

正規表現のパターンを指定し、インスタンスを生成します。コンストラクター - Regex クラス (System.Text.RegularExpressions) | MSDN

public Regex(
    string pattern,       // 正規表現パターン
    RegexOptions options, // 正規表現オプション
    TimeSpan matchTimeout // タイムアウト時間
)
Regex コンストラクター (String, RegexOptions, TimeSpan) (System.Text.RegularExpressions) | MSDN

無効なpatternを指定すると、ArgumentExceptionが投げられます。optionsを省略するとRegexOptions.Noneが、matchTimeoutを省略するとタイムアウトしません。

patternの内容を予測できない場合は、タイムアウトを指定するのが安全です。タイムアウト値を使用する - .NET の正規表現に関するベスト プラクティス | Microsoft Learn

string input = "AAAAAAAAAAaaaaaaaaaa!";
string pattern = @"^[0-9A-Z]([-.\w]*[0-9A-Z])*$";

Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(10));
// RegexMatchTimeoutException「パターンと入力文字列との照合中に、RegEx エンジンがタイムアウトしました。これは、非常に大きな入力、入れ子になった量指定子によって生じた過剰なバックトラッキング、前方参照などの要因を含む、さまざまな原因によって発生する可能性があります。」
RegexOptions 列挙型
列挙子 意味
None オプションなし

ECMAScript、RightToLeft、IgnoreCase、IgnorePatternWhitespace、CultureInvariant、ExplicitCaptureを指定しないのと同じ 既定のオプション - 正規表現のオプション | Microsoft Learn

Compiled アセンブリにコンパイルすることを指示。起動は遅くなるが、実行は早くなる コンパイルされた正規表現 - 正規表現のオプション | Microsoft Learn .net - How does RegexOptions.Compiled work? - Stack Overflow
ECMAScript ECMAScriptに準拠した動作とする ECMAScript 一致の動作 - 正規表現のオプション | Microsoft Learn
RightToLeft 右から左に検索
IgnoreCase 検索時に、大文字/小文字を区別しない
IgnorePatternWhitespace エスケープされていない空白を、パターンから除外する
CultureInvariant 言語の文化的な違いを無視することを指示
ExplicitCapture 名前のないグループをキャプチャしない
Multiline 複数行モード
Singleline 単一行モード
RegexOptions 列挙型 (System.Text.RegularExpressions) | Microsoft Learn

Multiline

複数行モードとできます。これにより文字列の末尾に加え、改行文字 (\n) にも一致するようになります。ただし\r\nには一致しないため、その必要があるならば\r?$と指定します。複数行モード - 正規表現のオプション | Microsoft Learn

Regex.Matches("A\r\nA\r\nA", "^A$", RegexOptions.Multiline).Count; // 1
Regex.Matches("A\r\nA\r\nA", "^A\r?$", RegexOptions.Multiline).Count; // 3

メソッド

メソッド 機能
IsMatch(String) 正規表現に一致するかどうか判定できる
Match(String) 正規表現に一致する、最初の1つを取得できる
Matches(String) 正規表現に一致する、すべての文字列を取得できる
Replace(String, String) 正規表現に一致するすべての文字列を、置換文字列に置換できる
   
メソッド - Regex クラス (System.Text.RegularExpressions) | Microsoft Learn

Match()

public Match Match(
    string input
)
Regex.Match メソッド (String) (System.Text.RegularExpressions) | MSDN

検索結果は戻り値のMatchオブジェクトで確認できます。それのSuccessプロパティがtrueならば一致しており、falseならば不一致です。一致した結果は、その部分文字列のValueプロパティで取得できます。取得できるのは最初の一致のみで、すべてを取得するにはMatches()を用います。

Match match = new Regex("[0-9]+").Match("ab123");
// Index: 2
// Length: 3
// Name: "0"
// Success: true
// Value: "123"

Matches()

public MatchCollection Matches(
    string input
)
Regex.Matches メソッド (String) (System.Text.RegularExpressions) | MSDN

一致するすべての結果は、NextMatch()で順に取得する方法もあります。

Regex regex = new Regex(pattern);
Match m = regex.Match(text);

while (m.Success)
{
    // m.Value 一致した1つの結果
    m = m.NextMatch();
}

Replace()

public string Replace(
    string input,      // 一致する対象を検索する文字列
    string replacement // 置換文字列
)
Replace(String, String) - Regex.Replace メソッド (System.Text.RegularExpressions) | Microsoft Learn

パターンに一致した場合は置換された文字列を、さもなくば置換前の元の文字列が返されます。

string text = "abc123def";
Regex regex = new Regex("[0-9]+");

string r1 = regex.Replace(text, "X"); // "abcXdef"
string r2 = Regex.Replace("abc", "(a)(b)(c)", "$3$2$1"); // "cba"

検索を開始する位置を指定するには、次のオーバーロードを用います。

public string Replace (
    string input,
    string replacement,
    int count,  // 置換を実行する最大数
    int startat // 検索を開始する位置
    );
Replace(String, String, Int32, Int32) - Regex.Replace メソッド (System.Text.RegularExpressions) | Microsoft Learn

静的メソッド

くり返し使用しないパターンならば、静的メソッドから呼び出す方法もあります。

Match match             = Regex.Match(text, "[0-9]+");
MatchCollection matches = Regex.Matches(text, "[0-9]+");
string str              = Regex.Replace(text, "[0-9]+", "A");

なおこれらは、次のように生成したオブジェクトからメソッドを呼び出すことと同じ結果を得られます。

Match match             = new Regex("[0-9]+").Match(text);
MatchCollection matches = new Regex("[0-9]+").Matches(text);
string str              = new Regex("[0-9]+").Replace(text, "A");

Escape()

リテラルが正規表現のメタ文字として解釈されないように、エスケープできます。

Character Escapes in .NET Regular Expressions | Microsoft Learn

public static string Escape (string str);
Regex.Escape(String) メソッド (System.Text.RegularExpressions) | Microsoft Learn
string str = Regex.Escape("\\,*,+,?,|,{,[,(,),^,$,.,#, ");
// "\\,\*,\+,\?,\|,\{,\[,\(,\),\^,\$,\.,\#,\ "

実行方法

方法 手順 特徴
静的正規表現 (static regular expressions) インスタンス化せず、Regexクラスの静的メソッドを呼び出す 使用したパターンは内部にキャッシュされる。その数は既定で15だが、Regex.CacheSizeで変更できる。

.NET Framework 2.0 SP1以降では、静的メソッドの呼び出しのみがキャッシュされる

解釈される正規表現 (interpreted regular expressions) Regexオブジェクトをインスタンス化し、解釈される正規表現のインスタンス メソッドを呼び出す 始動時間は短いが、実行時間が長い。メソッドの呼び出し回数が少ない場合に有効
コンパイルされる正規表現 (compiled regular expressions) Regexオブジェクトをインスタンス化し、コンパイルされた正規表現のインスタンス メソッドを呼び出す 始動時間は長いが、実行時間が短い。メソッドの呼び出し回数が多い場合に有効
アセンブリにコンパイルされる正規表現 (compiled to an assembly regular expressions) 特定の正規表現パターンのRegexオブジェクトを作成し、コンパイルして、アセンブリに保存する。そして実行時にそれを読み込み、そのメソッドを呼び出す メソッドの呼び出し回数を特定できない場合に有効

解釈またはコンパイルされる正規表現のいずれが効率的かは、正規表現の複雑さや処理対象によって異なるため、実際に実行時間を計測して検討します。

Matchクラス

クラス階層

Matchクラスの継承関係は次のようになっており、CaptureとGroupを拡張したものとなっています。

  • System.Object
    • System.Text.RegularExpressions.Capture
      • System.Text.RegularExpressions.Group
        • System.Text.RegularExpressions.Match

プロパティ

プロパティ 内容
string Name キャプチャ グループの名前
bool Success trueならば、対象が見つかった
int Index 部分文字列が見つかった元の文字列内の開始位置
int Length 部分文字列の長さ
string Value キャプチャされた部分文字列
GroupCollection Groups 一致したグループのコレクション
     
プロパティ - Match クラス (System.Text.RegularExpressions) | Microsoft Learn

Groups

一致したグループのコレクション (GroupCollection) を取得できます。

MatchCollectionクラス

MatchCollection クラス (System.Text.RegularExpressions) | Microsoft Learn

Groupクラス

個々のグループを表します。

必要なときのみグループをキャプチャするようにします。キャプチャはグループ化を(?:subexpression)としたり、ExplicitCaptureオプションを指定することで無効にできます。必要なときにのみキャプチャする - .NET の正規表現に関するベスト プラクティス | Microsoft Learn

string text = "ab_12 cd_34";
Regex regex = new Regex("([a-z]+)_([0-9]+)");

Match match = regex.Match(text);
// match.Value           "ab_12"
// match.Groups.Count    3
// match.Groups[0].Value "ab_12"
// match.Groups[1].Value "ab"
// match.Groups[2].Value "12"

MatchCollection matches = regex.Matches(text);
// matches[0].Groups[1].Value "ab"
// matches[1].Groups[1].Value "cd"

名前付きグループ (named group)

(?<name>subexpression)または(?'name'subexpression)の形式で、グループに名前を付けられます。一致した名前付き部分式 - 正規表現でのコンストラクトのグループ化 | Microsoft Learn

Match match = new Regex("[a-z]+(?<NAME>[0-9]+)").Match("ab123");
// match.Groups.Count 2
// match.Groups[0].Name "0"
// match.Groups[0].Value "ab123"
// match.Groups[1].Name "NAME"
// match.Groups[1].Value "123"

// match.Groups["NAME"].Value "123"

先後読み

パターンに一致することの検証だけが必要ならば、先後読みを用います。

   
ゼロ幅の肯定 先読みアサーション (Zero-width positive lookahead assertions) (?=subexpression)
ゼロ幅の否定 先読みアサーション (Zero-width negative lookahead assertions) (?!subexpression)
ゼロ幅の肯定 後読みアサーション (Zero-width positive lookbehind assertions) (?<=subexpression)
ゼロ幅の否定 後読みアサーション (Zero-width negative lookbehind assertions) (?<!subexpression)
ゼロ幅の肯定先読みアサーション - 正規表現でのコンストラクトのグループ化 | Microsoft Learn

RegexMatchTimeoutExceptionクラス

RegexMatchTimeoutException クラス (System.Text.RegularExpressions) | Microsoft Learn

正規表現パターン

文字クラス

単語境界 (word boundary)

\b

単語文字 (Word character)

ECMAScript準拠の指定をした場合は\w[a-zA-Z_0-9]と同じですが、さもなくば[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]です。単語に使用される文字: \w - .NET 正規表現での文字クラス | Microsoft Learn

Unicode カテゴリ (Unicode category)

p{Lu}p{Ll}のように指定します。サポートされている Unicode 一般カテゴリ - .NET 正規表現での文字クラス | Microsoft Learn

Regex.Match("abcDEF123", "\\p{Lu}+"); // "DEF"
カテゴリ 説明
Lu Letter, Uppercase A、À、Ͱ、Ϣ、ϴ
Ll Letter, Lowercase a、µ、ͱ
Lt Letter, Titlecase Dž、Lj、ᾈ
Lm Letter, Modifier ʰ、ʲ、ˇ
Nd Number, Decimal Digit 0、٠、߀、०、০、০
Nl Number, Letter ᛮ、Ⅰ、ⅽ、〇、𒐀
     
Unicode Character Categories

特定の文字がどのカテゴリに属しているかは、Char.GetUnicodeCategory()で確認できます。Char.GetUnicodeCategory メソッド (System) | Microsoft Learn

Char.GetUnicodeCategory('a'); // LowercaseLetter
Char.GetUnicodeCategory('1'); // DecimalDigitNumber
Char.GetUnicodeCategory('@'); // OtherPunctuation
Char.GetUnicodeCategory('あ'); // OtherLetter

Unicode ブロック (Unicode block)

コードポイントの範囲を定義する、ブロック名で指定します。サポートされている名前付きブロック - .NET 正規表現での文字クラス | Microsoft Learn

Regex.Match("abcあいうアイウ", "\\p{IsHiragana}+") // "あいう"

たとえばp{IsHiragana}は、U+3040~U+309Fの範囲に一致します。

ブロック名 コードポイントの範囲
IsHiragana 3040~309F
IsKatakana 30A0~30FF
IsCJKUnifiedIdeographs 4E00~9FFF
IsCJKUnifiedIdeographsExtensionA 3400~4DBF
IsCJKCompatibilityIdeographs F900~FAFF
   
Microsoft Learnから検索