
# 텍스트 검색

Greph의 텍스트 모드는 순회한 파일 트리에서 바이트 단위로 줄을 검색합니다. `greph` CLI와 `Greph::searchText()` 퍼사드의 기본 모드입니다. 출력은 grep, ripgrep 및 대부분의 편집기 통합 기능이 파싱하는 표준 `file:line:content` 형식을 사용합니다.

## 빠른 예제

```bash
# Regex search across the current directory
./vendor/bin/greph "function\s+\w+"

# Fixed-string search across src/
./vendor/bin/greph -F "function" src

# Case-insensitive whole-word search
./vendor/bin/greph -F -i -w "function" src

# Two lines of context around each match
./vendor/bin/greph -F -C 2 "TODO" src

# Stop after the first three matches per file
./vendor/bin/greph -F -m 3 "TODO" src

# Files that contain the pattern
./vendor/bin/greph -F -l "TODO" src

# Files that do not contain the pattern
./vendor/bin/greph -F -L "TODO" src

# Count matches per file
./vendor/bin/greph -F -c "TODO" src

# Inverted match
./vendor/bin/greph -F -v "TODO" src/notes.txt
```

## 패턴

기본적으로 패턴은 PCRE2 정규 표현식으로 처리됩니다. 엔진은 PHP의 `preg_*` 함수를 사용하므로 문법은 [PHP PCRE 참고 문서](https://www.php.net/manual/en/pcre.pattern.php)와 일치합니다.

`-F`로 정규식 엔진을 끄면 패턴을 리터럴 바이트 시퀀스로 처리합니다. 고정 문자열 모드는 가장 빠른 경로입니다. 매칭에 `strpos()`를 사용하고 PCRE2 컴파일 단계를 완전히 건너뜁니다.

`-i`은 두 모드 모두 대소문자를 구분하지 않게 합니다. `-w`은 매치 양쪽에 단어 경계를 추가합니다.

## 파일 필터링

Greph은 검색 전에 파일 트리를 순회합니다. 이 순회기는 AST 모드 및 인덱스 모드와 공유되므로 동일한 필터 플래그가 모든 모드에 적용됩니다.

| 플래그 | 효과 |
|---|---|
| `--type NAME` | 지정된 유형 별칭(`php`, `js`, `md`, ...)과 일치하는 파일만 포함 |
| `--type-not NAME` | 지정된 유형 별칭과 일치하는 파일 제외 |
| `--glob GLOB` | 경로가 GLOB과 일치하는 파일만 포함. 반복 사용 가능. |
| `--no-ignore` | `.gitignore` 또는 `.grephignore`을 따르지 않음 |
| `--hidden` | 숨김 파일 포함 |

순회기는 기본적으로 `.gitignore`과 `.grephignore`을 따르고, 첫 512바이트에서 널 바이트가 감지된 바이너리 파일은 건너뛰며, 파일 크기를 10 MiB로 제한합니다. 두 제한 모두 `WalkOptions`를 통해 설정할 수 있습니다.

전체 기본 제공 유형 별칭 목록은 [API / FileTypeFilter](https://greph.inline0.dev/ko/docs/api#grephwalkerfiletypefilter)를 참조하세요.

## 컨텍스트, 개수 및 파일 전용 모드

```bash
# Two lines before and after each match
./vendor/bin/greph -F -C 2 "needle" src

# Two lines after, no lines before
./vendor/bin/greph -F -A 2 "needle" src

# Two lines before, no lines after
./vendor/bin/greph -F -B 2 "needle" src

# Count matches per file
./vendor/bin/greph -F -c "needle" src

# List matching files only
./vendor/bin/greph -F -l "needle" src

# List non-matching files only
./vendor/bin/greph -F -L "needle" src
```

`-c`, `-l` 및 `-L`은 모든 줄을 메모리에 올리지 않도록 포매터를 건너뜁니다. "개수"와 "위치"를 묻는 쿼리에 적합한 모드입니다.

## 병렬 검색

`-j N`을 전달하면 검색을 N개의 워커에 분배합니다. Greph은 워커 풀에 `pcntl_fork()`를 사용하며, `ext-pcntl`을 사용할 수 없으면 단일 프로세스 실행으로 대체합니다.

```bash
./vendor/bin/greph -F -j 8 "function" src
```

퍼사드는 파일 수, 모드 및 패턴 형태를 바탕으로 병렬 실행에 드는 오버헤드를 감수할 가치가 있는지 계산합니다. 임계값보다 낮으면 단일 프로세스로 실행합니다. 휴리스틱은 [고급 / 병렬 워커](https://greph.inline0.dev/ko/docs/advanced/parallel)를 참조하세요.

## JSON 출력

`--json`은 grep 형식을 화면에서 긁어오지 않고도 후속 도구가 파싱할 수 있는 구조화된 페이로드를 출력합니다:

```bash
./vendor/bin/greph --json -F "function" src
```

```json
[
  {
    "file": "src/Greph.php",
    "matches": [
      {
        "line": 31,
        "column": 1,
        "content": "final class Greph",
        "matched_text": "function",
        "captures": []
      }
    ]
  }
]
```

`rg` 래퍼는 대신 ripgrep 이벤트 형태의 JSON를 출력합니다. 기존 소비자가 ripgrep 스키마를 기대하는 경우 사용하세요.

## 프로그래밍 방식 사용

```php
use Greph\Greph;
use Greph\Text\TextSearchOptions;

$results = Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(
        fixedString: true,
        caseInsensitive: true,
        beforeContext: 1,
        afterContext: 1,
        jobs: 4,
    ),
);

foreach ($results as $file) {
    foreach ($file->matches as $match) {
        echo "{$file->file}:{$match->line}:{$match->content}\n";
    }
}
```

결과 객체에 관한 설명은 [API / 결과 객체](https://greph.inline0.dev/ko/docs/api#result-objects)에 있습니다.

## 작동 방식

텍스트 엔진에는 두 가지 경로가 있습니다:

- **리터럴 경로**: `-F`이 설정되면 64 KiB 버퍼 리더를 통해 `strpos()` 검색을 실행하고, 줄 번호를 위해 개행을 추적합니다. 정규식 컴파일 단계는 없습니다.
- **정규식 경로**: `-F`가 설정되지 않으면 Greph가 작은 PCRE 형태 분석기(`Greph\Text\LiteralExtractor`)를 사용해 패턴에서 리터럴 부분 문자열을 추출하고 이를 `strpos()` 사전 필터로 사용합니다. 사전 필터를 통과한 줄은 JIT가 활성화된 컴파일된 PCRE2 패턴으로 매칭합니다.

두 경로 모두 I/O에 동일한 `BufferedReader`을 사용합니다. 리더는 줄마다 `fgets()`을 호출하는 대신 64 KiB 단위로 읽으므로 대용량 파일에서 시스템 호출 횟수가 크게 줄어듭니다.

반복 작업에서는 [인덱스 텍스트 모드](https://greph.inline0.dev/ko/docs/indexed/text)가 버퍼 리더 대신 미리 준비된 트라이그램 및 식별자 포스팅 저장소를 사용해 대부분의 파일을 건너뜁니다.
