> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 字串操作（Str 類別）

> 以實用範例說明使用 Laravel Str 類別與 Stringable（Fluent Strings）進行字串操作。

## 什麼是 Str 類別

`Illuminate\Support\Str` 類別提供豐富的字串操作方法。相較於個別呼叫 PHP 的標準字串函式，可用統一介面直覺處理字串。

Laravel 的字串操作有兩種風格：

* **靜態方法風格**：`Str::slug($title, '-')` — 適合單次操作
* **Fluent 風格（method chain）**：`Str::of($title)->slug('-')->limit(50)` — 可將多個操作串起來寫

```php theme={null}
use Illuminate\Support\Str;

// 靜態方法
$slug = Str::slug('My New Blog Post', '-');
// 'my-new-blog-post'

// Fluent（Str::of）
$result = Str::of('  My New Blog Post: Part 1  ')
    ->trim()
    ->slug('-')
    ->limit(30);
// 'my-new-blog-post-part-1'
```

<Info>
  `str()` 全域 helper 函式與 `Str::of()` 等效。可寫成 `str('hello')->upper()`。
</Info>

## 大小寫轉換

轉換字串大小寫（大寫、小寫、命名法）的方法。常用於資料庫欄位名或 API 回應鍵值的轉換。

### `Str::camel()` / `Str::snake()` / `Str::kebab()` / `Str::studly()`

```php theme={null}
use Illuminate\Support\Str;

// camelCase（開頭小寫）
Str::camel('foo_bar');        // 'fooBar'
Str::camel('user_profile_id'); // 'userProfileId'

// snake_case
Str::snake('fooBar');         // 'foo_bar'
Str::snake('UserProfile');    // 'user_profile'

// kebab-case
Str::kebab('fooBar');         // 'foo-bar'

// StudlyCase（PascalCase）
Str::studly('foo_bar');       // 'FooBar'
Str::studly('user-profile');  // 'UserProfile'
```

### `Str::lower()` / `Str::upper()` / `Str::title()`

```php theme={null}
use Illuminate\Support\Str;

Str::lower('LARAVEL');         // 'laravel'
Str::upper('laravel');         // 'LARAVEL'
Str::title('hello world');     // 'Hello World'
```

## Slug 與 URL

### `Str::slug()` — 產生 URL 友善的 slug

產生文章或頁面 URL 時的必備方法。將空格與特殊字元轉換為 URL 安全的字串。

```php theme={null}
use Illuminate\Support\Str;

Str::slug('Laravel フレームワーク', '-');
// 'laravel'（日文不會被轉為 ASCII 而被移除）

Str::slug('My New Blog Post', '-');
// 'my-new-blog-post'

Str::slug('Hello World!', '_');
// 'hello_world'
```

<Tip>
  包含中文／日文時 slug 可能為空。若想使用中文 slug，可另外搭配羅馬拼音轉換函式庫，或考慮使用 ID、時間戳作為 URL。
</Tip>

### 用 `Str::of()` 從 slug 產生到驗證一次完成

```php theme={null}
use Illuminate\Support\Str;

$title = '  My New Blog Post: Part 1!  ';

$slug = Str::of($title)
    ->trim()
    ->slug('-')
    ->limit(50);
// 'my-new-blog-post-part-1'
```

## 字串截斷

### `Str::limit()` — 依字元數截斷

在列表顯示文章內文或留言時產生預覽文字的方法。

```php theme={null}
use Illuminate\Support\Str;

$text = 'Laravelは美しいWebアプリケーションを作るためのPHPフレームワークです。';

// 截斷至 20 字元（預設會於尾端加上 "..."）
Str::limit($text, 20);
// 'Laravelは美しいWebアプリケー...'

// 自訂尾端字串
Str::limit($text, 20, ' → 続きを読む');
// 'Laravelは美しいWebアプリケー → 続きを読む'

// 不在單字中間切斷（英文文字用）
Str::limit('The quick brown fox jumps over the lazy dog', 20, preserveWords: true);
// 'The quick brown fox...'
```

### `Str::words()` — 依單字數截斷

```php theme={null}
use Illuminate\Support\Str;

Str::words('Perfectly balanced, as all things should be.', 3, ' >>>');
// 'Perfectly balanced, as >>>'
```

## 字串搜尋與確認

### `Str::contains()` — 是否包含子字串

```php theme={null}
use Illuminate\Support\Str;

Str::contains('This is my name', 'my');
// true

// 以陣列檢查多個候選（包含任一即可）
Str::contains('This is my name', ['my', 'your']);
// true

// 忽略大小寫
Str::contains('This is my name', 'MY', ignoreCase: true);
// true
```

### `Str::startsWith()` / `Str::endsWith()`

```php theme={null}
use Illuminate\Support\Str;

Str::startsWith('https://laravel.com', 'https://');
// true

Str::startsWith('https://laravel.com', ['https://', 'http://']);
// true

Str::endsWith('photo.jpg', '.jpg');
// true

Str::endsWith('photo.jpg', ['.jpg', '.png', '.gif']);
// true
```

### `Str::is()` — 萬用字元樣式比對

```php theme={null}
use Illuminate\Support\Str;

Str::is('foo*', 'foobar');
// true

Str::is('*/user/*', '/admin/user/profile');
// true

// 忽略大小寫
Str::is('F*', 'foo', ignoreCase: true);
// true
```

## 字串轉換與置換

### `Str::replace()` — 置換字串

```php theme={null}
use Illuminate\Support\Str;

Str::replace('8.x', '13.x', 'Laravel 8.x');
// 'Laravel 13.x'

// 忽略大小寫置換
Str::replace('laravel', 'Symphony', 'I love Laravel', caseSensitive: false);
// 'I love Symphony'
```

### `Str::replaceArray()` — 依序以陣列置換

```php theme={null}
use Illuminate\Support\Str;

$string = '預定為 ? 至 ?';

$result = Str::replaceArray('?', ['上午9點', '下午5點'], $string);
// '預定為 上午9點 至 下午5點'
```

### `Str::replaceMatches()` — 以正則表達式置換

```php theme={null}
use Illuminate\Support\Str;

// 從電話號碼移除非數字
Str::replaceMatches('/[^0-9]/', '', '(03) 1234-5678');
// '0312345678'

// 以 closure 動態產生置換內容
Str::replaceMatches('/\d+/', fn ($matches) => '[' . $matches[0] . ']', '1つ 2個 3本');
// '[1]つ [2]個 [3]本'
```

### `Str::remove()` — 移除字串

```php theme={null}
use Illuminate\Support\Str;

Str::remove('e', 'Peter Piper picked a peck of pickled peppers.');
// 'Ptr Pipr pickd a pck of pickld ppprs.'

// 以陣列刪除多個字串
Str::remove(['foo', 'bar'], 'foo and bar and baz');
// ' and  and baz'
```

### `Str::squish()` — 移除多餘空白

```php theme={null}
use Illuminate\Support\Str;

Str::squish('  Laravel   Framework  ');
// 'Laravel Framework'
```

## 字串前後操作

### `Str::before()` / `Str::after()`

```php theme={null}
use Illuminate\Support\Str;

// 指定字串之前的部分
Str::before('test@example.com', '@');
// 'test'

// 指定字串之後的部分
Str::after('test@example.com', '@');
// 'example.com'

// 以最後出現的位置為基準
Str::afterLast('App\Http\Controllers\UserController', '\\');
// 'UserController'

Str::beforeLast('App\Http\Controllers\UserController', '\\');
// 'App\Http\Controllers'
```

### `Str::between()` — 取得兩字串之間

```php theme={null}
use Illuminate\Support\Str;

Str::between('[debug] Error occurred in module', '[', ']');
// 'debug'
```

### `Str::start()` / `Str::finish()` — 確保以特定字元開頭／結尾

若已經以該字元開頭，不會重複加入（不會加倍）。

```php theme={null}
use Illuminate\Support\Str;

// 確保以 '/' 開頭
Str::start('users/profile', '/');
// '/users/profile'

Str::start('/users/profile', '/');
// '/users/profile'（不會加倍）

// 確保以 '/' 結尾
Str::finish('https://example.com', '/');
// 'https://example.com/'
```

### `Str::chopStart()` / `Str::chopEnd()` — 移除特定前綴／後綴

```php theme={null}
use Illuminate\Support\Str;

Str::chopStart('https://laravel.com', 'https://');
// 'laravel.com'

// 以陣列處理多個樣式
Str::chopStart('http://laravel.com', ['https://', 'http://']);
// 'laravel.com'

Str::chopEnd('UserController.php', '.php');
// 'UserController'
```

## 遮罩與安全性

### `Str::mask()` — 遮罩字串

用於隱藏 email 或電話號碼的部分。

```php theme={null}
use Illuminate\Support\Str;

// 從第 4 字元起以 '*' 遮罩
Str::mask('yamada@example.com', '*', 4);
// 'yama**************'

// 只顯示尾端 4 字元（以負值指定 offset）
Str::mask('1234-5678-9012-3456', '*', -4);
// '***************3456'

// 指定範圍遮罩
Str::mask('yamada@example.com', '*', 3, 5);
// 'yam*****example.com'
```

### `Str::excerpt()` — 依上下文取出字串

用於搜尋結果的 snippet 顯示。

```php theme={null}
use Illuminate\Support\Str;

$text = 'Laravelは美しいWebアプリケーションを構築するためのPHPフレームワークです。';

Str::excerpt($text, 'PHP', ['radius' => 10]);
// '...ためのPHPフレームワー...'
```

## 隨機字串與識別碼

### `Str::random()` — 產生隨機字串

用於產生 token 或密碼重設用金鑰。

```php theme={null}
use Illuminate\Support\Str;

Str::random(32);
// 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'（32 字元英數字）
```

### `Str::uuid()` / `Str::ulid()` — 產生 UUID／ULID

```php theme={null}
use Illuminate\Support\Str;

(string) Str::uuid();
// '550e8400-e29b-41d4-a716-446655440000'

// 依時序可排序的 UUID (UUIDv7)
(string) Str::uuid7();

// ULID（可排序的 ID）
(string) Str::ulid();
// '01ARZ3NDEKTSV4RRFFQ69G5FAV'
```

### `Str::password()` — 產生安全密碼

```php theme={null}
use Illuminate\Support\Str;

Str::password(12);
// 包含大寫、小寫、數字、符號的 12 字元隨機字串
```

### `Str::counted()` — 帶數量的單數／複數

依數值轉為單複數，並連同格式化後的數值一併回傳。

```php theme={null}
use Illuminate\Support\Str;

Str::counted('order', 1);
// '1 order'

Str::counted('order', 1000);
// '1,000 orders'
```

Fluent 風格也可同樣使用：

```php theme={null}
Str::of('order')->counted(3);
// '3 orders'
```

<Tip>
  在英文 UI 中顯示筆數（分「1 件」與「2 件以上」）時很方便。逗號分隔的格式會自動套用。
</Tip>

## Fluent Strings（method chain）

以 `Str::of()` 或 `str()` 起頭會回傳 `Stringable` 實例，可鏈式呼叫方法。最後要作為字串使用時，用 `(string)` 轉換或在字串上下文中使用。

```php theme={null}
use Illuminate\Support\Str;

$result = Str::of('  hello world  ')
    ->trim()
    ->title()
    ->append('!')
    ->toString();
// 'Hello World!'
```

### 實用的 method chain 範例

**產生部落格文章 slug**

```php theme={null}
use Illuminate\Support\Str;

$slug = Str::of('  My New Blog Post: Part 1  ')
    ->trim()
    ->lower()
    ->slug('-')
    ->limit(50);
// 'my-new-blog-post-part-1'
```

**從 URL 擷取網域**

```php theme={null}
use Illuminate\Support\Str;

$domain = Str::of('https://www.example.com/path/to/page')
    ->after('//')
    ->before('/')
    ->chopStart('www.');
// 'example.com'
```

**使用者輸入的 sanitize**

```php theme={null}
use Illuminate\Support\Str;

$clean = Str::of($userInput)
    ->squish()          // 移除多餘空白
    ->limit(255)        // 限制長度
    ->toString();
```

**從類別名稱產生檔案路徑**

```php theme={null}
use Illuminate\Support\Str;

$path = Str::of('App\Http\Controllers\UserController')
    ->replace('\\', '/')
    ->append('.php')
    ->toString();
// 'App/Http/Controllers/UserController.php'
```

### 條件式 method chain（`when()`）

```php theme={null}
use Illuminate\Support\Str;

$result = Str::of('Laravel')
    ->when($isUppercase, fn ($str) => $str->upper())
    ->append(' Framework');
// $isUppercase 為 true 則 'LARAVEL Framework'
// 為 false 則 'Laravel Framework'
```

### `pipe()` — 插入任意 callback

```php theme={null}
use Illuminate\Support\Str;

$result = Str::of('my-slug')
    ->pipe(fn ($str) => $str->replace('-', '_'))
    ->upper()
    ->toString();
// 'MY_SLUG'
```

## `Str::of()` 可用主要方法一覽

Fluent Strings 可用的方法與靜態方法幾乎相同。以下為代表性的方法：

```php theme={null}
use Illuminate\Support\Str;

$str = Str::of('Hello, World!');

$str->length();           // 13
$str->upper();            // 'HELLO, WORLD!'
$str->lower();            // 'hello, world!'
$str->trim();             // 'Hello, World!'
$str->slug();             // 'hello-world'
$str->camel();            // 'hello,World!'（不移除符號）
$str->contains('World'); // true
$str->startsWith('Hello'); // true
$str->endsWith('!');      // true
$str->replace(',', '');   // 'Hello World!'
$str->prepend('>>> ');    // '>>> Hello, World!'
$str->append(' <<<');     // 'Hello, World! <<<'
$str->reverse();          // '!dlroW ,olleH'
$str->wordCount();        // 2
```

## 總結

<AccordionGroup>
  <Accordion title="常用 Str 方法一覽">
    | 方法                                      | 用途              |
    | --------------------------------------- | --------------- |
    | `Str::slug($str)`                       | 產生 URL 友善的 slug |
    | `Str::limit($str, $n)`                  | 依字元數截斷          |
    | `Str::contains($str, $needle)`          | 是否包含字串          |
    | `Str::startsWith($str, $needle)`        | 是否以指定字串開頭       |
    | `Str::endsWith($str, $needle)`          | 是否以指定字串結尾       |
    | `Str::replace($search, $replace, $str)` | 置換字串            |
    | `Str::camel($str)`                      | 轉為 camelCase    |
    | `Str::snake($str)`                      | 轉為 snake\_case  |
    | `Str::kebab($str)`                      | 轉為 kebab-case   |
    | `Str::studly($str)`                     | 轉為 StudlyCase   |
    | `Str::upper($str)`                      | 轉為大寫            |
    | `Str::lower($str)`                      | 轉為小寫            |
    | `Str::squish($str)`                     | 移除多餘空白          |
    | `Str::after($str, $search)`             | 取得指定字串之後        |
    | `Str::before($str, $search)`            | 取得指定字串之前        |
    | `Str::between($str, $from, $to)`        | 取得兩字串之間         |
    | `Str::mask($str, '*', $index)`          | 遮罩字串            |
    | `Str::random($length)`                  | 產生隨機字串          |
    | `Str::uuid()`                           | 產生 UUID         |
    | `Str::of($str)`                         | 開始 Fluent 風格    |
  </Accordion>

  <Accordion title="靜態方法 vs Fluent（Str::of）">
    **使用靜態方法的時機**：

    * 只做 1〜2 次轉換
    * 簡潔易讀的程式碼

    ```php theme={null}
    $slug = Str::slug($title);
    ```

    **使用 Fluent（Str::of）的時機**：

    * 要一次做 3 個以上的轉換
    * 需含條件分支（`when()`）
    * 想讓處理由上至下順讀

    ```php theme={null}
    $slug = Str::of($title)
        ->trim()
        ->lower()
        ->slug()
        ->limit(50);
    ```
  </Accordion>

  <Accordion title="Str 類別 vs PHP 標準函式">
    以 `Str` 類別取代 PHP 的 `strtolower()`、`substr()`、`str_replace()` 等標準函式可獲得：

    * 安全處理多位元組字元（中文／日文）（內部使用 `mb_*` 函式）
    * 以 method chain 整合處理
    * 不用記引數順序（一致的介面）
    * 統一使用 Laravel 的撰寫風格
  </Accordion>
</AccordionGroup>


## Related topics

- [Macroable trait](/zh-TW/advanced/macroable.md)
- [InteractsWithData trait](/zh-TW/advanced/interacts-with-data.md)
- [Fluent 類別](/zh-TW/advanced/fluent.md)
- [Lottery 類別](/zh-TW/advanced/lottery.md)
- [Core — AT Protocol 核心操作](/zh-TW/packages/laravel-bluesky/core.md)
