# 機能設計書 21-文字列検索・置換

## 概要

本ドキュメントは、Nushellにおける文字列検索・置換機能の設計仕様を記述する。

### 本機能の処理概要

文字列検索・置換機能は、入力文字列内の特定のパターンを検索し、一致する部分を別の文字列に置換する機能を提供する。テキスト処理、ログ解析、データクレンジングなど幅広い場面で活用される基本的な文字列操作機能である。

**業務上の目的・背景**：データ処理において、文字列の検索・置換は最も頻繁に必要とされる操作の一つである。ログファイルの解析、設定ファイルの編集、データのクレンジング、テキストの正規化など、様々な業務シーンで文字列のパターンマッチングと置換が必要となる。本機能により、シェルパイプライン内で効率的にテキスト変換処理を実行できる。

**機能の利用シーン**：
- ログファイル内の特定のパターンを検索・抽出する場合
- 設定ファイルのパラメータを一括置換する場合
- データファイル内の不要な文字列を除去・変換する場合
- ファイルパスやURLの正規化処理を行う場合

**主要な処理内容**：
1. `str contains` - 文字列内に部分文字列が含まれるかチェック
2. `str replace` - 文字列内のパターンを別の文字列に置換
3. `str index-of` - 部分文字列の開始位置を取得
4. `str starts-with` - 文字列が指定パターンで始まるかチェック
5. `str ends-with` - 文字列が指定パターンで終わるかチェック

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

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

## 関連画面

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

## 機能種別

データ変換 / 検索処理

## 入力仕様

### 入力パラメータ

#### str contains

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| string | String | Yes | 検索する部分文字列 | - |
| --ignore-case / -i | Switch | No | 大文字小文字を区別しない | - |
| rest | CellPath | No | データ構造内の対象セルパス | - |

#### str replace

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| find | String | Yes | 検索するパターン | - |
| replace | String/Closure | Yes | 置換文字列またはクロージャ | - |
| --all / -a | Switch | No | すべての出現箇所を置換 | - |
| --regex / -r | Switch | No | 正規表現モードを有効化 | - |
| --multiline / -m | Switch | No | 複数行モード（^$が行単位で動作） | - |
| --no-expand / -n | Switch | No | キャプチャグループを展開しない | - |

#### str index-of

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| string | String | Yes | 検索する部分文字列 | - |
| --end / -e | Switch | No | 末尾から検索 | - |
| --range / -r | Range | No | 検索範囲の指定 | - |
| --grapheme-clusters / -g | Switch | No | グラフィムクラスタでカウント | - |

### 入力データソース

パイプライン入力（文字列、リスト、テーブル、レコード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (str contains) | Bool | 部分文字列が含まれるかどうか |
| result (str replace) | String | 置換後の文字列 |
| result (str index-of) | Int | 部分文字列の開始位置（-1は未発見） |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ 文字列、リスト、テーブル、レコードを受け付ける
2. コマンド引数を解析する
   └─ 検索パターン、置換文字列、オプションフラグを取得
3. 入力値の型に応じた処理を実行
   └─ 文字列: 直接処理を適用
   └─ リスト: 各要素に対して処理を適用
   └─ テーブル/レコード: 指定されたセルパスに対して処理を適用
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{入力型判定}
    B -->|String| C[文字列処理実行]
    B -->|List| D[各要素に処理適用]
    B -->|Table/Record| E[セルパス指定処理]
    C --> F{正規表現モード?}
    F -->|Yes| G[Regexパターン構築]
    F -->|No| H[通常文字列検索]
    G --> I[パターンマッチング]
    H --> I
    I --> J[結果出力]
    D --> J
    E --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-21-1 | 大文字小文字区別 | --ignore-caseフラグで区別しない検索が可能 | str contains使用時 |
| BR-21-2 | 全置換モード | --allフラグで全出現箇所を置換 | str replace使用時 |
| BR-21-3 | 正規表現サポート | fancy_regexクレートを使用した高度なパターンマッチング | --regexフラグ使用時 |
| BR-21-4 | 未発見時の戻り値 | index-ofで文字列が見つからない場合は-1を返す | str index-of使用時 |

### 計算ロジック

正規表現モードではキャプチャグループ（`$1`, `$name`等）を置換文字列内で参照可能。クロージャモードでは、マッチした文字列を引数として受け取り、動的に置換文字列を生成できる。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OnlySupportsThisInputType | 型エラー | 文字列以外の型が入力された場合 | 文字列型を入力する |
| IncorrectValue | 正規表現エラー | 無効な正規表現パターン | パターン構文を確認 |
| RuntimeTypeMismatch | 型不一致 | クロージャが文字列を返さない | クロージャの戻り値を確認 |

### リトライ仕様

該当なし

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

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

## パフォーマンス要件

- 正規表現処理はfancy_regexクレートを使用し、バックトラック制限（デフォルト1,000,000）あり
- 大規模テキストの全置換は処理時間に注意が必要

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

- 正規表現パターンはユーザー入力を直接受け付けるため、ReDoS攻撃に注意
- バックトラック制限によりある程度の保護あり

## 備考

- `str contains`は定数式として評価可能（is_const = true）
- Unicode対応（グラフィムクラスタ単位での処理が可能）

---

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

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

### 推奨読解順序

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

文字列操作コマンドの引数構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | contains.rs | `crates/nu-command/src/strings/str_/contains.rs` | Arguments構造体の定義（9-13行目） |
| 1-2 | replace.rs | `crates/nu-command/src/strings/str_/replace.rs` | ReplacementValue enumの定義（6-9行目） |

**読解のコツ**: `CmdArgument` traitの`take_cell_paths`メソッドは、データ構造内の特定のパスに対して処理を適用するための共通パターン。

#### Step 2: エントリーポイントを理解する

コマンド実行の起点を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | contains.rs | `crates/nu-command/src/strings/str_/contains.rs` | `impl Command for StrContains`（21-148行目） |
| 2-2 | replace.rs | `crates/nu-command/src/strings/str_/replace.rs` | `impl Command for StrReplace`（30-256行目） |

**主要処理フロー**:
1. **57-72行目**: `run`メソッドで引数解析とoperate呼び出し
2. **150-180行目**: `action`関数で実際の文字列処理を実行

#### Step 3: 処理ロジックを理解する

実際の文字列検索・置換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | contains.rs | `crates/nu-command/src/strings/str_/contains.rs` | action関数（150-180行目）- 実際の検索処理 |
| 3-2 | replace.rs | `crates/nu-command/src/strings/str_/replace.rs` | action関数（258-415行目）- 置換処理とRegex処理 |
| 3-3 | index_of.rs | `crates/nu-command/src/strings/str_/index_of.rs` | action関数（159-242行目）- インデックス検索 |

**主要処理フロー**:
- **replace.rs 274行目**: no_regexの場合は通常の文字列置換
- **replace.rs 310-402行目**: 正規表現モードでのfancy_regex使用

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

```
StrContains::run / StrReplace::run
    │
    ├─ call.req() / call.has_flag()
    │      └─ 引数解析
    │
    └─ operate()  (nu_cmd_base::input_handler)
           │
           └─ action()
                  │
                  ├─ Value::String → 直接処理
                  │      └─ val.contains() / val.replace() / Regex::new()
                  │
                  └─ Value::Error → エラー伝播
```

### データフロー図

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

PipelineData ───▶ operate() ───▶ action() ───▶ Value
   │                  │               │
   │                  │               └─ 文字列処理
   │                  │                     ├─ contains → Bool
   │                  │                     ├─ replace → String
   │                  └─ 各要素に適用        └─ index-of → Int
   │
   └─ String / List / Table / Record
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| contains.rs | `crates/nu-command/src/strings/str_/contains.rs` | ソース | str contains コマンド実装 |
| replace.rs | `crates/nu-command/src/strings/str_/replace.rs` | ソース | str replace コマンド実装 |
| index_of.rs | `crates/nu-command/src/strings/str_/index_of.rs` | ソース | str index-of コマンド実装 |
| starts_with.rs | `crates/nu-command/src/strings/str_/starts_with.rs` | ソース | str starts-with コマンド実装 |
| ends_with.rs | `crates/nu-command/src/strings/str_/ends_with.rs` | ソース | str ends-with コマンド実装 |
| mod.rs | `crates/nu-command/src/strings/str_/mod.rs` | ソース | モジュール定義 |
| input_handler.rs | `crates/nu-cmd-base/src/input_handler.rs` | ソース | operate関数の共通処理 |
