Vai al contenuto

Ricerca nel testo

La modalità testo di Greph esegue una ricerca di byte orientata alle righe nell'albero dei file esplorato. È la modalità predefinita di greph CLI e della facade Greph::searchText(). L'output usa il formato canonico file:line:content, interpretato da grep, ripgrep e dalla maggior parte delle integrazioni degli editor.

Esempi rapidi

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

Pattern

Per impostazione predefinita, il pattern viene trattato come un'espressione regolare PCRE2. Le funzioni preg_* di PHP implementano il motore, quindi la sintassi corrisponde a quella del riferimento PCREPHP.

Disattivate il motore delle espressioni regolari con -F per trattare il pattern come una sequenza letterale di byte. La modalità a stringa fissa è il percorso rapido: usa strpos() per la corrispondenza e salta completamente la fase di compilazione PCRE2.

-i rende entrambe le modalità insensibili alle maiuscole. -w aggiunge i confini di parola ai lati della corrispondenza.

Filtraggio dei file

Greph esplora l'albero dei file prima della ricerca. Il walker è condiviso con la modalità AST e la modalità indicizzata, quindi gli stessi flag di filtro si applicano ovunque.

Flag Effetto
--type NAME Includi solo i file che corrispondono all'alias di tipo indicato (php, js, md, ...)
--type-not NAME Escludi i file che corrispondono all'alias di tipo indicato
--glob GLOB Includi solo i file il cui percorso corrisponde a GLOB. Ripetibile.
--no-ignore Ignora .gitignore e .grephignore
--hidden Includi i file nascosti

Per impostazione predefinita, il walker rispetta .gitignore e .grephignore, salta i file binari (rilevati dalla presenza di byte nulli nei primi 512 byte) e limita la dimensione dei file a 10 MiB. Entrambi i limiti sono configurabili tramite WalkOptions.

Per l'elenco completo degli alias di tipo integrati, consultate API / FileTypeFilter.

Contesto, conteggi e modalità per soli file

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 e -L interrompono anticipatamente il formatter, evitando di caricare in memoria tutte le righe. Sono le modalità adatte alle query «quanti» e «dove».

Scansioni parallele

Passate -j N per distribuire la scansione su N worker. Greph usa pcntl_fork() per il pool di worker e ripiega sull'esecuzione in un singolo processo quando ext-pcntl non è disponibile.

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

La facade calcola se l'esecuzione parallela vale il sovraccarico in base al numero di file, alla modalità e alla forma del pattern. Sotto la soglia, resta a processo singolo. Per i criteri euristici, consultate Avanzate / Worker paralleli.

Output JSON

--json genera un payload strutturato che gli strumenti a valle possono analizzare senza estrarre dati dal formato grep:

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

Il wrapper rg genera invece JSON strutturati come eventi ripgrep. Usatelo quando un consumer esistente si aspetta lo schema ripgrep.

Uso programmatico

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

Gli oggetti risultato sono descritti in API / Oggetti risultato.

Come funziona

Il motore di testo ha due percorsi:

  • Percorso letterale: quando è impostato -F, la ricerca usa strpos() su un lettore bufferizzato da 64 KiB e tiene traccia dei caratteri di nuova riga per numerare le righe. Non avviene alcuna compilazione di espressioni regolari.
  • Percorso con espressioni regolari: quando -F non è impostato, Greph estrae sottostringhe letterali dal pattern usando un piccolo analizzatore compatibile con PCRE (Greph\Text\LiteralExtractor) e le usa come pre-filtro strpos(). Le righe che superano il pre-filtro vengono poi confrontate con il pattern PCRE2 compilato, con JIT attivato.

Entrambi i percorsi usano lo stesso BufferedReader per l'I/O. Il lettore acquisisce blocchi da 64 KiB anziché fgets() per riga, riducendo drasticamente il numero di chiamate di sistema nei file grandi.

Per i carichi di lavoro ripetuti, la modalità testo indicizzata sostituisce il lettore bufferizzato con un archivio riscaldato di trigrammi e postings degli identificatori, saltando interamente la maggior parte dei file.