> ## 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의 문자열 조작에는 2개의 스타일이 있습니다.

* **정적 메서드 스타일**: `Str::slug($title, '-')` — 단발의 조작에 적합합니다
* **Fluent 스타일 (메서드 체인)**: `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()` 글로벌 헬퍼 함수는 `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'
```

## 슬러그와 URL

### `Str::slug()` — URL 프렌들리한 슬러그를 생성

기사나 페이지의 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>
  한국어를 포함하는 경우는 슬러그가 비게 될 수 있습니다. 한국어의 슬러그를 사용하고 싶은 경우는, 별도 로마자 변환 라이브러리를 조합하거나, ID나 타임스탬프를 URL에 사용하는 것을 검토해 주세요.
</Tip>

### `Str::of()`로 슬러그 생성부터 검증까지 일괄 처리

```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은 아름다운 웹 애플리케이션을 만들기 위한 PHP 프레임워크입니다.';

// 20문자로 자르기 (기본으로 말미에 "..."를 추가)
Str::limit($text, 20);
// 'Laravel은 아름다운 웹 애플리케...'

// 말미 문자열을 커스터마이즈
Str::limit($text, 20, ' → 계속 읽기');
// 'Laravel은 아름다운 웹 애플리케 → 계속 읽기'

// 단어의 도중에 자르지 않음 (영어 텍스트용)
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]/', '', '(02) 1234-5678');
// '0212345678'

// 클로저로 치환 내용을 동적으로 생성
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()` — 2개의 문자열 사이를 취득

```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()` — 문자열을 마스크

메일 주소나 전화번호의 일부를 감추는 처리에 사용합니다.

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

// 4문자째 이후를 '*'로 마스크
Str::mask('hong@example.com', '*', 4);
// 'hong************'

// 말미 4문자만 표시 (음의 값으로 오프셋)
Str::mask('1234-5678-9012-3456', '*', -4);
// '***************3456'

// 범위를 지정하여 마스크
Str::mask('hong@example.com', '*', 3, 5);
// 'hon*****xample.com'
```

### `Str::excerpt()` — 문맥 첨부로 문자열을 뽑아냄

검색 결과의 스니펫 표시 등에 사용합니다.

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

$text = 'Laravel은 아름다운 웹 애플리케이션을 구축하기 위한 PHP 프레임워크입니다.';

Str::excerpt($text, 'PHP', ['radius' => 10]);
// '...위한 PHP 프레임워크입...'
```

## 랜덤 문자열과 식별자

### `Str::random()` — 랜덤 문자열을 생성

토큰이나 비밀번호 리셋용의 키를 생성할 때에 사용합니다.

```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 (메서드 체인)

`Str::of()` 또는 `str()`로 시작하면, `Stringable` 인스턴스가 반환되며, 메서드를 체인할 수 있습니다. 최종적으로 문자열로서 사용하고 싶은 경우는 `(string)`으로 캐스트하거나, 문자열 컨텍스트로 사용합니다.

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

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

### 실용적인 메서드 체인의 예

**블로그 기사의 슬러그 생성**

```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'
```

**사용자 입력의 새니타이즈**

```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'
```

### 조건부 메서드 체인 (`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()` — 임의의 콜백을 끼움

```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 프렌들리한 슬러그 생성 |
    | `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)`        | 2문자열 사이를 취득      |
    | `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 표준 함수">
    PHP의 `strtolower()`, `substr()`, `str_replace()` 등의 표준 함수 대신에 `Str` 클래스를 사용함으로써:

    * 멀티바이트 문자(한국어)를 안전하게 다룰 수 있음 (`mb_*` 함수를 내부에서 사용)
    * 메서드 체인으로 처리를 정리할 수 있음
    * 인수의 순서를 외우지 않아도 됨 (일관된 인터페이스)
    * Laravel의 코드 스타일에 통일할 수 있음
  </Accordion>
</AccordionGroup>


## Related topics

- [Macroable 트레이트](/ko/advanced/macroable.md)
- [InteractsWithData 트레이트](/ko/advanced/interacts-with-data.md)
- [컬렉션의 고차 메시지](/ko/advanced/higher-order-messages.md)
- [Fluent 클래스](/ko/advanced/fluent.md)
- [Lottery 클래스](/ko/advanced/lottery.md)
