Pular para o conteúdo

Pesquisa de texto

O modo de texto de Greph faz uma pesquisa de bytes orientada a linhas em uma árvore de arquivos percorrida. É o modo padrão de greph CLI e da fachada Greph::searchText(). A saída usa o formato canônico file:line:content, interpretado por grep, ripgrep e pela maioria das integrações com editores.

Exemplos rápidos

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

Padrões

Por padrão, o padrão é tratado como uma expressão regular PCRE2. As funções de PHP preg_* dão suporte ao mecanismo, então a sintaxe corresponde à referência do PCREPHP.

Desative o mecanismo de regex com -F para tratar o padrão como uma sequência literal de bytes. O modo de string literal é o caminho rápido: usa strpos() para fazer a correspondência e ignora totalmente a etapa de compilação do PCRE2.

-i torna os dois modos insensíveis a maiúsculas e minúsculas. -w adiciona limites de palavra inteira em ambos os lados da correspondência.

Filtragem de arquivos

Greph percorre a árvore de arquivos antes de pesquisar. O percurso é compartilhado pelos modos AST e indexado, então os mesmos sinalizadores de filtragem se aplicam a todos eles.

Sinalizador Efeito
--type NAME Inclui apenas arquivos que correspondem ao alias de tipo indicado (php, js, md, ...)
--type-not NAME Exclui arquivos que correspondem ao alias de tipo indicado
--glob GLOB Inclui apenas arquivos cujos caminhos correspondem a GLOB. Pode ser repetido.
--no-ignore Ignora .gitignore e .grephignore
--hidden Inclui arquivos ocultos

Por padrão, o percurso respeita .gitignore e .grephignore, ignora arquivos binários (detectados por bytes nulos nos primeiros 512 bytes) e limita o tamanho dos arquivos a 10 MiB. Os dois limites podem ser configurados por WalkOptions.

Consulte API / FileTypeFilter para ver a lista completa dos aliases de tipo integrados.

Contexto, contagens e modos somente de arquivo

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 interrompem a execução do formatador antes que ele materialize todas as linhas. São os modos adequados para consultas de "quantos" e "onde".

Varreduras paralelas

Passe -j N para distribuir a varredura entre N workers. Greph usa pcntl_fork() para o pool de workers e recorre à execução em processo único quando ext-pcntl não está disponível.

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

A fachada calcula se a execução paralela compensa o custo adicional com base na quantidade de arquivos, no modo e no formato do padrão. Abaixo do limite, permanece em processo único. Consulte Avançado / Workers paralelos para ver as heurísticas.

Saída JSON

--json emite um conteúdo estruturado que ferramentas posteriores podem interpretar sem extrair informações da saída de 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": []
      }
    ]
  }
]

O wrapper rg emite um JSON estruturado como eventos ripgrep. Use-o quando um consumidor existente espera o esquema ripgrep.

Uso programático

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

Os objetos de resultado estão documentados em API / Objetos de resultado.

Como funciona

O mecanismo de texto tem dois caminhos:

  • Caminho literal: quando -F está definido, a pesquisa executa strpos() em um leitor com buffer de 64 KiB e acompanha as quebras de linha para numerar as linhas. Não há etapa de compilação de regex.
  • Caminho de regex: quando -F não está definido, Greph extrai trechos literais do padrão usando um pequeno analisador no formato PCRE (Greph\Text\LiteralExtractor) e os usa como pré-filtro strpos(). Em seguida, as linhas aprovadas pelo pré-filtro são comparadas com o padrão PCRE2 compilado, com JIT ativado.

Os dois caminhos usam o mesmo BufferedReader para E/S. O leitor lê blocos de 64 KiB em vez de fgets() por linha, o que reduz drasticamente a quantidade de chamadas de sistema em arquivos grandes.

Para cargas de trabalho repetidas, o modo de texto indexado indexado substitui o leitor com buffer por um índice de trigramas e ocorrências de identificadores aquecido e ignora a maioria dos arquivos por completo.