
# Iskanje besedila

Besedilni način orodja Greph izvaja iskanje bajtov po vrsticah v pregledanem drevesu datotek. To je privzeti način fasade `greph` CLI in fasade `Greph::searchText()`. Izhod uporablja kanonično obliko `file:line:content`, ki jo razčlenjujejo grep, ripgrep in večina integracij v urejevalnikih.

## Hitri primeri

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

## Vzorci

Vzorec se privzeto obravnava kot regularni izraz PCRE2. Mehanizem poganjajo funkcije `preg_*` orodja PHP, zato se sintaksa ujema z [referenco PCRE](https://www.php.net/manual/en/pcre.pattern.php)PHP.

Mehanizem regularnih izrazov izklopite z `-F`, da se vzorec obravnava kot zaporedje dobesednih bajtov. Način fiksnih nizov je hitrejša pot: za ujemanje uporablja `strpos()` in v celoti preskoči prevajanje PCRE2.

`-i` omogoči iskanje brez razlikovanja med velikimi in malimi črkami v obeh načinih. `-w` doda meje cele besede na obeh straneh ujemanja.

## Filtriranje datotek

Greph pred iskanjem pregleda drevo datotek. Pregledovalnik si delita načina AST in indeksirano iskanje, zato povsod veljajo iste zastavice za filtriranje.

| Zastavica | Učinek |
|---|---|
| `--type NAME` | Vključi samo datoteke, ki se ujemajo z navedenim vzdevkom vrste (`php`, `js`, `md`, ...) |
| `--type-not NAME` | Izključi datoteke, ki se ujemajo z navedenim vzdevkom vrste |
| `--glob GLOB` | Vključi samo datoteke, katerih poti se ujemajo z GLOB. Zastavico je mogoče ponoviti. |
| `--no-ignore` | Ne upoštevaj `.gitignore` ali `.grephignore` |
| `--hidden` | Vključi skrite datoteke |

Pregledovalnik privzeto upošteva `.gitignore` in `.grephignore`, preskoči binarne datoteke (prepozna jih po ničelnih bajtih v prvih 512 bajtih) in omeji velikost datotek na 10 MiB. Obe omejitvi je mogoče nastaviti prek `WalkOptions`.

Za celoten seznam vgrajenih vzdevkov vrst glejte [API / Filter vrst datotek](https://greph.inline0.dev/sl/docs/api#grephwalkerfiletypefilter).

## Kontekst, števila in načini samo z datotekami

```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` in `-L` preskočijo oblikovalnik, zato jim ni treba ustvariti vseh vrstic. Primerni so za poizvedbe »koliko« in »kje«.

## Vzporedno pregledovanje

Za razpošiljanje pregledovanja med N delavcev podajte `-j N`. Greph za skupino delavcev uporablja `pcntl_fork()` in preklopi na enoprocesno izvajanje, če `ext-pcntl` ni na voljo.

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

Fasada na podlagi števila datotek, načina in oblike vzorca izračuna, ali se vzporedno izvajanje splača glede na dodatne stroške. Pod pragom ostane pri enem procesu. O hevristikah preberite v razdelku [Napredno / Vzporedni delavci](https://greph.inline0.dev/sl/docs/advanced/parallel).

## Izhod JSON

`--json` ustvari strukturiran zapis, ki ga lahko nadaljnja orodja razčlenijo, ne da bi zajemala zaslonski izpis v obliki 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": []
      }
    ]
  }
]
```

Ovoj `rg` namesto tega ustvari JSON v obliki dogodkov ripgrep. Uporabite ga, kadar obstoječi porabnik pričakuje shemo ripgrep.

## Uporaba v kodi

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

Objekti rezultatov so opisani v razdelku [API / Objekti rezultatov](https://greph.inline0.dev/sl/docs/api#result-objects).

## Kako deluje

Besedilni mehanizem ima dve poti:

- **Pot z dobesednim nizom**: ko je nastavljen `-F`, iskanje poteka z uporabo `strpos()` prek medpomnilniškega bralnika velikosti 64 KiB, hkrati pa se spremljajo znaki za novo vrstico zaradi oštevilčenja vrstic. Korak prevajanja regularnega izraza ne obstaja.
- **Pot z regularnim izrazom**: ko `-F` ni nastavljen, Greph z majhnim analizatorjem v obliki PCRE (`Greph\Text\LiteralExtractor`) iz vzorca izlušči dobesedne podnize in jih uporabi kot filter `strpos()`. Vrstice, ki prestanejo ta filter, se nato primerjajo s prevedenim vzorcem PCRE2 z omogočenim JIT.

Obe poti za V/I uporabljata isti `BufferedReader`. Bralnik bere v kosih po 64 KiB namesto `fgets()` na vrstico, kar pri velikih datotekah močno zmanjša število sistemskih klicev.

Pri ponavljajočih se opravilih [indeksirani besedilni način](https://greph.inline0.dev/sl/docs/indexed/text) nadomesti medpomnilniški bralnik z ogretim skladiščem trigramov in indeksov pojavitev identifikatorjev ter v celoti preskoči večino datotek.
