Wyszukiwanie tekstu
Tryb tekstowy Greph wyszukuje bajty wiersz po wierszu w przemierzanym drzewie plików. Jest domyślnym trybem greph CLI oraz fasady Greph::searchText(). Wyniki są w kanonicznym formacie file:line:content, który analizują grep, ripgrep i większość integracji z edytorami.
Szybkie przykłady
# 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
Wzorce
Domyślnie wzorzec jest traktowany jako wyrażenie regularne PCRE2. Za silnikiem stoją funkcje preg_* z PHP, więc składnia odpowiada dokumentacji PCREPHP.
Wyłącz silnik wyrażeń regularnych za pomocą -F, aby traktować wzorzec jako dosłowną sekwencję bajtów. Tryb stałego ciągu to szybka ścieżka: do dopasowywania używa strpos() i całkowicie pomija etap kompilacji PCRE2.
-i sprawia, że w obu trybach wielkość liter nie ma znaczenia. -w dodaje granice całych słów po obu stronach dopasowania.
Filtrowanie plików
Greph przemierza drzewo plików przed wyszukiwaniem. Ten sam mechanizm przemierzania jest używany w trybie AST i trybie indeksowanym, dlatego wszędzie obowiązują te same flagi filtrowania.
| Flaga | Działanie |
|---|---|
--type NAME |
Uwzględnia tylko pliki pasujące do nazwanego aliasu typu (php, js, md, ...) |
--type-not NAME |
Wyklucza pliki pasujące do nazwanego aliasu typu |
--glob GLOB |
Uwzględnia tylko pliki, których ścieżki pasują do GLOB. Można powtarzać. |
--no-ignore |
Ignoruje .gitignore lub .grephignore |
--hidden |
Uwzględnia ukryte pliki |
Mechanizm przemierzania domyślnie respektuje .gitignore i .grephignore, pomija pliki binarne (wykrywane na podstawie bajtów null w pierwszych 512 bajtach) i ogranicza rozmiar pliku do 10 MiB. Oba limity można skonfigurować za pomocą WalkOptions.
Pełną listę wbudowanych aliasów typów znajdziesz w API / FileTypeFilter.
Kontekst, liczniki i tryby tylko dla plików
# 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 i -L pomijają formatowanie, dzięki czemu nie trzeba wczytywać wszystkich wierszy do pamięci. To odpowiednie tryby dla zapytań „ile” i „gdzie”.
Skanowanie równoległe
Przekaż -j N, aby rozdzielić skanowanie między N procesów roboczych. Greph używa pcntl_fork() do utworzenia puli procesów roboczych i przechodzi na wykonanie jednego procesu, gdy ext-pcntl jest niedostępne.
./vendor/bin/greph -F -j 8 "function" src
Fasada ocenia, czy wykonanie równoległe jest warte dodatkowego narzutu, na podstawie liczby plików, trybu i kształtu wzorca. Poniżej progu pozostaje przy jednym procesie. Zobacz Zaawansowane / Procesy robocze równoległe, aby poznać heurystyki.
Dane wyjściowe JSON
--json emituje uporządkowany ładunek danych, który narzędzia dalszego przetwarzania mogą analizować bez pobierania wyników w formacie grep:
./vendor/bin/greph --json -F "function" src
[
{
"file": "src/Greph.php",
"matches": [
{
"line": 31,
"column": 1,
"content": "final class Greph",
"matched_text": "function",
"captures": []
}
]
}
]
Opakowanie rg emituje zamiast tego JSON w formie zdarzeń ripgrep. Użyj go, gdy istniejący odbiorca oczekuje schematu ripgrep.
Użycie programowe
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";
}
}
Obiekty wynikowe opisano w API / Obiekty wynikowe.
Jak to działa
Silnik tekstowy ma dwie ścieżki:
- Ścieżka dosłowna: gdy ustawiono
-F, wyszukiwanie wykonujestrpos()na buforowanym czytniku o rozmiarze 64 KiB i śledzi znaki nowej linii na potrzeby numeracji wierszy. Nie ma etapu kompilacji wyrażeń regularnych. - Ścieżka wyrażeń regularnych: gdy nie ustawiono
-F, Greph wyodrębnia dosłowne podciągi ze wzorca za pomocą prostego analizatora w stylu PCRE (Greph\Text\LiteralExtractor) i używa ich jako filtra wstępnegostrpos(). Wiersze, które przejdą filtr wstępny, są następnie dopasowywane do skompilowanego wzorca PCRE2 z włączonym JIT.
Obie ścieżki używają tego samego BufferedReader do operacji wejścia i wyjścia. Czytnik odczytuje dane w porcjach po 64 KiB zamiast fgets() na wiersz, co znacznie zmniejsza liczbę wywołań systemowych w przypadku dużych plików.
Przy powtarzających się zadaniach indeksowany tryb tekstowy zastępuje buforowany czytnik rozgrzanym magazynem trójgramów i wystąpień identyfikatorów, całkowicie pomijając większość plików.