# 機能設計書 24-パース・解析

## 概要

本ドキュメントは、Nushellにおけるパース・解析機能の設計仕様を記述する。

### 本機能の処理概要

パース・解析機能は、非構造化テキストデータからパターンマッチングにより構造化データを抽出する機能を提供する。ログファイルの解析、コマンド出力の構造化、データ抽出など、テキスト処理において高度な変換を実現する。

**業務上の目的・背景**：システムログ、コマンド出力、テキスト形式のデータなど、多くの情報は非構造化テキストとして存在する。これらを構造化データ（テーブル）に変換することで、Nushellのパイプライン処理で効率的に分析・操作できるようになる。正規表現による柔軟なパターンマッチングにより、様々な形式のテキストデータに対応できる。

**機能の利用シーン**：
- システムログから日時、レベル、メッセージを抽出する場合
- コマンド出力を構造化データに変換する場合
- テキストファイルから特定のパターンにマッチするデータを抽出する場合
- データ変換のためのパターンマッチングを行う場合

**主要な処理内容**：
1. `parse` - パターンによる構造化データの抽出
2. `detect columns` - 列構造の自動検出と分割

**関連システム・外部連携**：特になし。Nushell内部の文字列処理として動作する。

**権限による制御**：特になし。すべてのユーザーが使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 結果表示画面 | コマンド実行結果の表示 |

## 機能種別

データ変換 / パターン抽出

## 入力仕様

### 入力パラメータ

#### parse

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pattern | String | Yes | マッチングパターン | - |
| --regex / -r | Switch | No | フル正規表現モードを有効化 | - |
| --backtrack / -b | Int | No | 正規表現のバックトラック上限 | デフォルト1,000,000 |

### 入力データソース

パイプライン入力（文字列、リスト、ByteStream）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Table | パターンにマッチした構造化データ |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ 文字列、リスト、ByteStreamを受け付ける
2. パターン文字列を解析する
   └─ 簡易パターン: {name}形式を正規表現に変換
   └─ 正規表現モード: パターンをそのまま使用
3. fancy_regexで正規表現をコンパイル
   └─ バックトラック上限を設定
4. 各入力行に対してパターンマッチングを実行
5. マッチしたキャプチャグループからレコードを生成
6. 結果をテーブルとして出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{正規表現モード?}
    B -->|Yes| C[パターンをそのまま使用]
    B -->|No| D[簡易パターンを正規表現に変換]
    C --> E[fancy_regex でコンパイル]
    D --> E
    E --> F{入力型判定}
    F -->|String| G[単一文字列処理]
    F -->|List| H[リスト処理]
    F -->|ByteStream| I[ストリーム処理]
    G --> J[captures_iter でマッチング]
    H --> J
    I --> J
    J --> K[レコード生成]
    K --> L[テーブル出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-1 | 簡易パターン変換 | {name}形式を(?P<name>.*?)正規表現に変換 | --regexなしの場合 |
| BR-24-2 | アンダースコア破棄 | {_}はキャプチャせず破棄される | 簡易パターン使用時 |
| BR-24-3 | 名前なしキャプチャ | 名前なしグループはcapture0, capture1...として出力 | 正規表現モード |
| BR-24-4 | バックトラック制限 | fancy_regexのバックトラック上限を設定可能 | 常時 |

### 計算ロジック

簡易パターンの変換ルール：
- `{foo}` → `(?P<foo>.*?)`（名前付きキャプチャグループ）
- `{_}` → `(?:.*?)`（非キャプチャグループ、破棄用）
- `{{` → `{`（エスケープ）
- パターン全体は`(?s)\A`と`\z`で囲まれる

## データベース操作仕様

該当なし（メモリ内での文字列処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| GenericError | 正規表現エラー | 無効な正規表現パターン | パターン構文を確認 |
| DelimiterError | 区切りエラー | {の対応する}がない場合 | パターン構文を確認 |
| OnlySupportsThisInputType | 型エラー | 文字列以外の型が入力された場合 | 文字列型を入力する |
| PipelineMismatch | 型不一致 | ストリーム内で期待しない型が出現 | 入力データを確認 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし（ステートレス処理）

## パフォーマンス要件

- fancy_regexクレートを使用し、高度な正規表現機能（先読み、後読み等）をサポート
- バックトラック制限によりReDoS攻撃を防御（デフォルト1,000,000）
- ParseIterを使用したストリーミング処理でメモリ効率を向上

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

- ユーザー入力の正規表現パターンはReDoS攻撃に注意
- バックトラック制限により攻撃の影響を軽減

## 備考

- `parse`は定数式として評価可能（is_const = true）
- fancy_regexにより先読み（lookahead）、後読み（lookbehind）などの高度な正規表現機能を使用可能

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

パースコマンドの全体構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parse.rs | `crates/nu-command/src/strings/parse.rs` | Parse構造体とCommand実装（7-155行目） |

**読解のコツ**: parseコマンドは簡易パターン（{name}形式）と正規表現モードの両方をサポート。build_regex関数が簡易パターンを正規表現に変換する。

#### Step 2: パターン変換を理解する

簡易パターンから正規表現への変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parse.rs | `crates/nu-command/src/strings/parse.rs` | build_regex関数（279-338行目）- パターン変換処理 |

**主要処理フロー**:
1. **280行目**: 出力文字列を`(?s)\A`で開始
2. **285-295行目**: `{`を検出するまでプレーンテキストを処理
3. **303-328行目**: `{name}`形式のキャプチャグループを構築
4. **336行目**: 出力文字列を`\z`で終了

#### Step 3: マッチング処理を理解する

実際のパターンマッチングとレコード生成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parse.rs | `crates/nu-command/src/strings/parse.rs` | operate関数（157-277行目）- 入力型に応じた処理分岐 |
| 3-2 | parse.rs | `crates/nu-command/src/strings/parse.rs` | ParseIter構造体（340-382行目）- ストリーミング処理 |
| 3-3 | parse.rs | `crates/nu-command/src/strings/parse.rs` | captures_to_value関数（384-409行目）- キャプチャからレコード生成 |

**主要処理フロー**:
- **176-178行目**: 正規表現をコンパイル（バックトラック制限付き）
- **187-195行目**: キャプチャグループ名の抽出
- **197-277行目**: 入力型（String, List, ByteStream）に応じた処理
- **397-406行目**: キャプチャグループからレコードを構築

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

```
Parse::run
    │
    ├─ call.req("pattern") - パターン取得
    ├─ call.has_flag("regex") - 正規表現モード判定
    │
    └─ operate()
           │
           ├─ build_regex() (簡易パターンの場合)
           │      └─ {name} → (?P<name>.*?)
           │
           ├─ RegexBuilder::new().backtrack_limit().build()
           │
           └─ 入力型に応じた処理
                  │
                  ├─ String → captures_iter() → captures_to_value()
                  ├─ List → ParseIter
                  └─ ByteStream → lines() → ParseIter
```

### データフロー図

```
[入力]               [処理]                    [出力]

String/List ───▶ operate() ───▶ regex.captures_iter() ───▶ Table
   │                  │               │
   │                  │               └─ captures_to_value()
   │                  │                     │
   │                  └─ パターン            └─ Record生成
   │                      変換                   （列: キャプチャ名）
   │
   └─ "hi there" + "{foo} {bar}"
          ↓
       [[foo, bar]; [hi, there]]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| parse.rs | `crates/nu-command/src/strings/parse.rs` | ソース | parse コマンド実装 |
| detect_columns.rs | `crates/nu-command/src/strings/detect_columns.rs` | ソース | detect columns コマンド実装 |
| mod.rs | `crates/nu-command/src/strings/mod.rs` | ソース | stringsモジュール定義 |
