Ga naar de inhoud

Tekst zoeken

De tekstmodus van Greph zoekt regel voor regel naar bytes in een doorlopen bestandsboom. Dit is de standaardmodus van greph CLI en de Greph::searchText()-façade. De uitvoer gebruikt de canonieke file:line:content-indeling die grep, ripgrep en de meeste editorintegraties kunnen verwerken.

Snelle voorbeelden

Shell
# 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

Patronen

Standaard wordt het patroon behandeld als een reguliere PCRE2-expressie. De preg_*-functies van PHP vormen de basis van de engine, waardoor de syntaxis overeenkomt met de PCRE-referentiePHP.

Schakel de regex-engine uit met -F om het patroon als een letterlijke bytereeks te behandelen. De modus voor vaste tekenreeksen is de snelle route: deze gebruikt strpos() om overeenkomsten te vinden en slaat de compilatiestap van PCRE2 volledig over.

-i maakt beide modi hoofdletterongevoelig. -w voegt woordgrenzen toe aan beide kanten van de overeenkomst.

Bestanden filteren

Greph doorloopt de bestandsboom voordat er wordt gezocht. De doorloopfunctie wordt gedeeld met de AST-modus en de geïndexeerde modus, dus overal gelden dezelfde filtervlaggen.

Vlag Effect
--type NAME Alleen bestanden opnemen die overeenkomen met de genoemde typealias (php, js, md, ...)
--type-not NAME Bestanden uitsluiten die overeenkomen met de genoemde typealias
--glob GLOB Alleen bestanden opnemen waarvan de paden overeenkomen met GLOB. Herhaalbaar.
--no-ignore .gitignore of .grephignore niet respecteren
--hidden Verborgen bestanden opnemen

De doorloopfunctie houdt standaard rekening met .gitignore en .grephignore, slaat binaire bestanden over (herkend aan null-bytes in de eerste 512 bytes) en beperkt de bestandsgrootte tot 10 MiB. Beide limieten zijn instelbaar via WalkOptions.

Zie API / FileTypeFilter voor de volledige lijst met ingebouwde typealiassen.

Context, aantallen en modi voor alleen bestanden

Shell
# 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 en -L slaan de formatter over, zodat ze niet alle regels in het geheugen hoeven te laden. Dit zijn de aangewezen modi voor vragen als "hoeveel" en "waar".

Parallelle scans

Geef -j N door om de scan over N workers te verdelen. Greph gebruikt pcntl_fork() voor de workerpool en valt terug op uitvoering in één proces wanneer ext-pcntl niet beschikbaar is.

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

De façade bepaalt op basis van het aantal bestanden, de modus en de vorm van het patroon of parallelle uitvoering de extra overhead waard is. Onder de drempel blijft de uitvoering beperkt tot één proces. Zie Geavanceerd / Parallelle workers voor de heuristieken.

Uitvoer van JSON

--json geeft een gestructureerde payload uit die downstreamtools kunnen verwerken zonder de grep-indeling uit het scherm te scrapen:

Shell
./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": []
      }
    ]
  }
]

De wrapper rg geeft in plaats daarvan ripgrep in de vorm van JSON-gebeurtenissen uit. Gebruik deze als een bestaande afnemer het schema ripgrep verwacht.

Programmatisch gebruik

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

De resultaatobjecten worden beschreven in API / Resultaatobjecten.

Werking

De tekstengine heeft twee routes:

  • Letterlijke route: wanneer -F is ingesteld, voert de zoekopdracht strpos() uit met een gebufferde reader van 64 KiB en houdt deze nieuwe regels bij voor de regelnummers. Er is geen regex-compilatiestap.
  • Regex-route: wanneer -F niet is ingesteld, haalt Greph letterlijke subtekenreeksen uit het patroon met een eenvoudige PCRE-achtige analyser (Greph\Text\LiteralExtractor) en gebruikt deze als strpos()-voorfilter. Regels die de voorfilter doorstaan, worden vervolgens vergeleken met het gecompileerde PCRE2-patroon, met JIT ingeschakeld.

Beide routes gebruiken dezelfde BufferedReader voor I/O. De reader leest blokken van 64 KiB in plaats van fgets() per regel, waardoor het aantal systeemaanroepen bij grote bestanden aanzienlijk afneemt.

Voor herhaalde workloads vervangt de geïndexeerde tekstmodus de gebufferde reader door een opgewarmde trigram- en identifier-index en slaat deze de meeste bestanden volledig over.