# 機能設計書: System.Text.RegularExpressions（正規表現）

## 1. 機能概要

### 1.1 機能名
System.Text.RegularExpressions（正規表現）

### 1.2 機能ID
FUNC-011

### 1.3 機能説明
.NET ランタイムにおける正規表現（Regular Expression）処理機能を提供するライブラリ。文字列のパターンマッチング、検索、置換、分割などの高度な文字列操作を実現する。Perl5互換の正規表現構文をサポートし、コンパイル済み正規表現やソースジェネレーターによる事前生成など、複数の実行モードを提供する。

### 1.4 関連画面
- なし（基盤ライブラリのため直接的な関連画面は存在しない）

## 2. 機能要件

### 2.1 入力仕様

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| pattern | string | Yes | 正規表現パターン文字列 |
| input | string/ReadOnlySpan<char> | Yes | マッチング対象の入力文字列 |
| options | RegexOptions | No | 正規表現オプション（大文字小文字無視、マルチラインなど） |
| matchTimeout | TimeSpan | No | マッチング処理のタイムアウト時間 |
| replacement | string | No | 置換処理時の置換文字列 |

### 2.2 出力仕様

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| Match | Match | 単一のマッチ結果 |
| MatchCollection | MatchCollection | 複数のマッチ結果コレクション |
| bool | bool | IsMatch()によるマッチ成否 |
| string | string | Replace()による置換後文字列 |
| string[] | string[] | Split()による分割結果配列 |
| int | int | Count()によるマッチ数 |

### 2.3 処理フロー

```
入力文字列
    │
    ▼
┌─────────────────────┐
│   正規表現パーサー     │ ← RegexParser.cs
│   (パターン解析)       │
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│   正規表現ツリー       │ ← RegexNode, RegexTree
│   (構文木構築)         │
└─────────────────────┘
    │
    ├────────────────┬────────────────┐
    ▼                ▼                ▼
┌─────────┐    ┌─────────┐    ┌─────────┐
│インタプリタ│   │コンパイル│   │ソース    │
│モード    │    │モード    │    │生成モード │
└─────────┘    └─────────┘    └─────────┘
    │                │                │
    └────────────────┴────────────────┘
                     │
                     ▼
┌─────────────────────┐
│   マッチングエンジン    │ ← RegexRunner
│   (実行)              │
└─────────────────────┘
    │
    ▼
マッチ結果
```

## 3. 詳細設計

### 3.1 クラス構成

#### 3.1.1 主要クラス

| クラス名 | 責務 |
|----------|------|
| Regex | 正規表現の主要エントリーポイント。パターンのコンパイルとマッチング操作を提供 |
| RegexParser | 正規表現パターン文字列を構文解析し、RegexTreeを構築 |
| RegexNode | 正規表現の構文木ノード。各種パターン要素を表現 |
| RegexRunner | 正規表現マッチングの実行エンジン基底クラス |
| Match | マッチング結果を格納。グループ情報やキャプチャを含む |
| Group | キャプチャグループの結果を格納 |
| Capture | 単一のキャプチャ結果（位置と値） |

### 3.2 メソッド仕様

#### 3.2.1 Regex.IsMatch()

```csharp
public static bool IsMatch(string input, string pattern);
public static bool IsMatch(string input, string pattern, RegexOptions options);
public static bool IsMatch(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);
public static bool IsMatch(ReadOnlySpan<char> input, string pattern);
public bool IsMatch(string input);
public bool IsMatch(string input, int startat);
public bool IsMatch(ReadOnlySpan<char> input);
```

**説明**: 入力文字列が正規表現パターンにマッチするかを判定する。

**処理内容**:
1. パターンをコンパイル（静的メソッドの場合はキャッシュを使用）
2. RegexRunnerを使用してマッチング実行
3. マッチ成否を返却

#### 3.2.2 Regex.Match()

```csharp
public static Match Match(string input, string pattern);
public Match Match(string input);
public Match Match(string input, int startat);
public Match Match(string input, int beginning, int length);
```

**説明**: 入力文字列から最初のマッチを検索し、Match オブジェクトを返す。

#### 3.2.3 Regex.Matches()

```csharp
public static MatchCollection Matches(string input, string pattern);
public MatchCollection Matches(string input);
public MatchCollection Matches(string input, int startat);
```

**説明**: 入力文字列から全てのマッチを検索し、MatchCollectionを返す。

#### 3.2.4 Regex.Replace()

```csharp
public static string Replace(string input, string pattern, string replacement);
public static string Replace(string input, string pattern, MatchEvaluator evaluator);
public string Replace(string input, string replacement);
public string Replace(string input, string replacement, int count);
public string Replace(string input, MatchEvaluator evaluator);
```

**説明**: 正規表現にマッチした部分を指定した文字列またはデリゲートの結果で置換する。

#### 3.2.5 Regex.Split()

```csharp
public static string[] Split(string input, string pattern);
public string[] Split(string input);
public string[] Split(string input, int count);
```

**説明**: 正規表現パターンをデリミタとして文字列を分割する。

### 3.3 RegexOptions 列挙型

| オプション | 値 | 説明 |
|------------|-----|------|
| None | 0 | デフォルト動作 |
| IgnoreCase | 1 | 大文字小文字を区別しない |
| Multiline | 2 | ^と$が行頭・行末にもマッチ |
| ExplicitCapture | 4 | 名前付きグループのみキャプチャ |
| Compiled | 8 | ILにコンパイルして高速化 |
| Singleline | 16 | .が改行にもマッチ |
| IgnorePatternWhitespace | 32 | パターン内の空白を無視 |
| RightToLeft | 64 | 右から左へマッチング |
| ECMAScript | 256 | ECMAScript準拠モード |
| CultureInvariant | 512 | カルチャ非依存 |
| NonBacktracking | 1024 | バックトラックなしモード |

### 3.4 性能考慮事項

#### 3.4.1 正規表現キャッシュ
- 静的メソッド使用時、コンパイル済みRegexはキャッシュされる
- デフォルトキャッシュサイズ: 15
- `Regex.CacheSize` プロパティで調整可能

#### 3.4.2 実行モード選択

| モード | 特徴 | 推奨用途 |
|--------|------|----------|
| インタプリタ | 起動が速い、実行は中程度 | 1回限りの使用 |
| Compiled | 起動が遅い、実行が速い | 繰り返し使用 |
| ソース生成 | ビルド時生成、最高速 | ホットパス |
| NonBacktracking | 線形時間保証 | DoS対策が必要な場合 |

#### 3.4.3 タイムアウト設定
- `Regex.InfiniteMatchTimeout`: タイムアウトなし（デフォルト）
- 信頼できない入力にはタイムアウト設定を推奨
- `RegexMatchTimeoutException`がスローされる

## 4. エラー処理

### 4.1 例外一覧

| 例外 | 発生条件 |
|------|----------|
| ArgumentNullException | pattern または input が null |
| ArgumentException | 無効な正規表現パターン |
| ArgumentOutOfRangeException | startat が範囲外 |
| RegexMatchTimeoutException | マッチング処理がタイムアウト |
| RegexParseException | パターン解析エラー |

### 4.2 エラーハンドリング方針
- パターンの構文エラーは RegexParseException で報告
- ランタイムエラーは適切な例外型でスロー
- タイムアウトは明示的に捕捉して処理することを推奨

## 5. セキュリティ考慮事項

### 5.1 ReDoS（Regular Expression Denial of Service）対策
- `RegexOptions.NonBacktracking` の使用を推奨
- タイムアウトの設定を必須化
- 信頼できない入力パターンの検証

### 5.2 入力検証
- ユーザー入力をパターンとして使用する場合は `Regex.Escape()` を使用
- 最大入力長の制限を推奨

## 6. コードリーディングガイド

### 6.1 推奨読解順序

1. **データ構造の理解**
   - `RegexNode.cs`: 構文木ノードの定義
   - `RegexTree.cs`: 構文木全体の構造

2. **エントリーポイント**
   - `Regex.cs`: 主要APIの定義（IsMatch, Match, Replace等）
   - **34-45行目**: コンストラクタでのパターン初期化
   - **63-75行目**: 静的IsMatchメソッドの実装

3. **パターン解析**
   - `RegexParser.cs`: パターン文字列の構文解析
   - **Parse()メソッド**: パターン文字列からRegexTreeを構築
   - **ScanRegex()**: 正規表現要素のスキャン

4. **マッチング実行**
   - `RegexRunner.cs`: マッチングエンジンの基底クラス
   - `RegexInterpreter.cs`: インタプリタモードの実装

### 6.2 プログラム呼び出し階層図

```
Regex.IsMatch(input, pattern)
    │
    ├── GetOrAdd() [キャッシュからRegex取得]
    │       │
    │       └── new Regex(pattern, options)
    │               │
    │               ├── RegexParser.Parse()
    │               │       │
    │               │       └── ScanRegex()
    │               │               └── RegexNode構築
    │               │
    │               └── RegexTree構築
    │
    └── IsMatch(input)
            │
            └── Run(input, startat)
                    │
                    ├── RegexRunner.Scan()
                    │       │
                    │       └── Go() [マッチング実行]
                    │
                    └── Match結果生成
```

### 6.3 データフロー図

```
┌──────────────────┐
│ パターン文字列     │
│ "\\d{3}-\\d{4}"  │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│  RegexParser     │
│  構文解析        │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│  RegexTree       │
│  ├─Concatenation │
│  │ ├─Loop{3,3}   │
│  │ │ └─Digit     │
│  │ ├─One('-')    │
│  │ └─Loop{4,4}   │
│  │   └─Digit     │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│  RegexRunner     │
│  マッチング実行   │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│  Match結果       │
│  Index, Length,  │
│  Value, Groups   │
└──────────────────┘
```

### 6.4 読解のコツ

#### 6.4.1 RegexNode の種類
RegexNode.cs では多数のノード種類が定義されている:
- `One`: 単一文字マッチ
- `Multi`: 複数文字シーケンス
- `Set`: 文字クラス `[a-z]`
- `Loop`: 量指定子 `*`, `+`, `{n,m}`
- `Capture`: グループキャプチャ `()`
- `Alternate`: 選択 `|`

#### 6.4.2 最適化フェーズ
RegexTree構築後、いくつかの最適化が適用される:
- 冗長ノードの削除
- 固定プレフィックスの抽出
- アンカー最適化

### 6.5 関連ファイル一覧

| パス | 種別 | 役割 |
|------|------|------|
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs` | ソース | 主要エントリーポイント |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs` | ソース | パターン構文解析 |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs` | ソース | 構文木ノード定義 |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexTree.cs` | ソース | 構文木構造 |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexRunner.cs` | ソース | マッチングエンジン基底 |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexInterpreter.cs` | ソース | インタプリタ実装 |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCompiler.cs` | ソース | ILコンパイラ |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Match.cs` | ソース | マッチ結果クラス |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Group.cs` | ソース | グループ結果クラス |
| `src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Capture.cs` | ソース | キャプチャ結果クラス |

## 7. 使用例

### 7.1 基本的なマッチング

```csharp
// 電話番号パターンのマッチ
string pattern = @"\d{3}-\d{4}";
string input = "電話番号: 123-4567";

if (Regex.IsMatch(input, pattern))
{
    Match match = Regex.Match(input, pattern);
    Console.WriteLine($"マッチ: {match.Value}"); // 123-4567
}
```

### 7.2 グループキャプチャ

```csharp
string pattern = @"(?<area>\d{3})-(?<local>\d{4})";
Match match = Regex.Match("123-4567", pattern);

Console.WriteLine($"市外局番: {match.Groups["area"].Value}");  // 123
Console.WriteLine($"市内番号: {match.Groups["local"].Value}"); // 4567
```

### 7.3 置換処理

```csharp
string result = Regex.Replace(
    "Hello World",
    @"\bWorld\b",
    "Universe"
);
// 結果: "Hello Universe"
```

## 8. テスト観点

### 8.1 単体テスト観点
- 各種正規表現パターンのマッチ正確性
- エッジケース（空文字列、特殊文字）の処理
- オプション組み合わせの動作確認
- タイムアウト動作の検証

### 8.2 性能テスト観点
- 大量データに対するマッチング速度
- 複雑パターンの処理時間
- キャッシュ効率の測定

## 9. 変更履歴

| バージョン | 日付 | 変更内容 |
|------------|------|----------|
| 1.0 | 2026-01-30 | 初版作成 |
