
# Textsökning

Grephs textläge är en radbaserad bytesökning genom ett genomsökt filträd. Det är standardläget i `greph` CLI och fasaden `Greph::searchText()`. Utdata använder det kanoniska formatet `file:line:content`, som grep, ripgrep och de flesta editorintegrationer kan tolka.

## Snabba exempel

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

## Mönster

Som standard behandlas mönstret som ett reguljärt PCRE2-uttryck. PHPs `preg_*`-funktioner ligger till grund för motorn, så syntaxen motsvarar [PHP PCRE-referensen](https://www.php.net/manual/en/pcre.pattern.php).

Stäng av regexmotorn med `-F` för att behandla mönstret som en bokstavlig bytesekvens. Läget med fasta strängar är den snabba vägen: det använder `strpos()` för matchning och hoppar helt över PCRE2-kompileringen.

`-i` gör båda lägena skiftlägesokänsliga. `-w` lägger till ordgränser på båda sidor om matchningen.

## Filtrera filer

Greph går igenom filträdet före sökningen. Filträdsvandraren delas med AST-läget och det indexerade läget, så samma filterflaggor gäller överallt.

| Flagga | Effekt |
|---|---|
| `--type NAME` | Inkludera endast filer som matchar det namngivna typaliaset (`php`, `js`, `md`, ...) |
| `--type-not NAME` | Exkludera filer som matchar det namngivna typaliaset |
| `--glob GLOB` | Inkludera endast filer vars sökvägar matchar GLOB. Kan upprepas. |
| `--no-ignore` | Följ inte `.gitignore` eller `.grephignore` |
| `--hidden` | Inkludera dolda filer |

Filträdsvandraren respekterar `.gitignore` och `.grephignore` som standard, hoppar över binärfiler (identifieras genom nollbyte bland de första 512 byten) och begränsar filstorleken till 10 MiB. Båda gränserna kan konfigureras via `WalkOptions`.

Se [API / FileTypeFilter](https://greph.inline0.dev/sv/docs/api#grephwalkerfiletypefilter) för en fullständig lista över inbyggda typalias.

## Kontext, antal och lägen som endast visar filer

```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` och `-L` hoppar över formateraren så att varje rad inte behöver skapas i minnet. De passar för frågor om ”hur många” och ”var”.

## Parallella genomsökningar

Skicka med `-j N` för att fördela genomsökningen på N arbetare. Greph använder `pcntl_fork()` för arbetargruppen och återgår till körning i en process när `ext-pcntl` inte är tillgängligt.

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

Fasaden beräknar om parallell körning är värd omkostnaden utifrån antalet filer, läget och mönstrets form. Under tröskelvärdet körs allt i en process. Se [Avancerat / Parallella arbetare](https://greph.inline0.dev/sv/docs/advanced/parallel) för heuristiken.

## Utdata från JSON

`--json` skickar ut en strukturerad nyttolast som nedströmsverktyg kan tolka utan att skrapa grep-formatet:

```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": []
      }
    ]
  }
]
```

Omslaget `rg` skickar i stället ut ripgrep-händelseformad JSON. Använd det när en befintlig konsument förväntar sig schemat ripgrep.

## Programmatisk användning

```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";
    }
}
```

Resultatobjekten beskrivs i [API / Resultatobjekt](https://greph.inline0.dev/sv/docs/api#result-objects).

## Så fungerar det

Textmotorn har två sökvägar:

- **Bokstavlig sökväg**: när `-F` är inställt körs sökningen `strpos()` genom en buffrad läsare på 64 KiB som håller reda på radbrytningar för radnumrering. Ingen regexkompilering görs.
- **Regexsökväg**: när `-F` inte är inställt extraherar Greph bokstavliga delsträngar ur mönstret med en liten PCRE-formad analysator (`Greph\Text\LiteralExtractor`) och använder dem som ett `strpos()`-förfilter. Rader som passerar förfiltret matchas sedan mot det kompilerade PCRE2-mönstret med JIT aktiverat.

Båda sökvägarna använder samma `BufferedReader` för I/O. Läsaren läser i 64 KiB-block i stället för `fgets()` per rad, vilket minskar antalet systemanrop kraftigt för stora filer.

Vid upprepade arbetsbelastningar ersätter det [indexerade textläget](https://greph.inline0.dev/sv/docs/indexed/text) den buffrade läsaren med ett uppvärmt trigrambaserat index och ett index över identifierarträffar, och hoppar helt över de flesta filer.
