Търсене в текст
Текстовият режим на Greph търси ред по ред байтове в обходено дърво от файлове. Това е режимът по подразбиране на greph CLI и фасадата Greph::searchText(). Изходът е в каноничния формат file:line:content, който се обработва от grep, ripgrep и повечето интеграции с редактори.
Кратки примери
# 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
Шаблони
По подразбиране шаблонът се третира като регулярен израз PCRE2. Функциите preg_* на PHP осигуряват енджина, така че синтаксисът съответства на справочника за PCRE на PHP.
Изключете енджина за регулярни изрази с -F, за да третирате шаблона като буквална последователност от байтове. Режимът за точни низове е бързият вариант: използва strpos() за съвпадения и изцяло пропуска компилирането на PCRE2.
-i прави и двата режима нечувствителни към регистъра. -w добавя граници на цяла дума от двете страни на съвпадението.
Филтриране на файлове
Greph обхожда дървото от файлове преди търсенето. Обхождащият механизъм е споделен с AST режима и индексирания режим, така че едни и същи флагове за филтриране важат навсякъде.
| Флаг | Ефект |
|---|---|
--type NAME |
Включва само файловете, съответстващи на посочения псевдоним на тип (php, js, md, ...) |
--type-not NAME |
Изключва файловете, съответстващи на посочения псевдоним на тип |
--glob GLOB |
Включва само файлове, чиито пътища съответстват на GLOB. Може да се повтаря. |
--no-ignore |
Не спазва .gitignore или .grephignore |
--hidden |
Включва скритите файлове |
По подразбиране обхождащият механизъм спазва .gitignore и .grephignore, пропуска двоичните файлове (открива ги по нулевите байтове в първите 512 байта) и ограничава размера на файла до 10 MiB. И двете ограничения могат да се конфигурират чрез WalkOptions.
Вижте API / FileTypeFilter за пълния списък с вградени псевдоними на типове.
Контекст, бройки и режими само за файлове
# 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 и -L заобикалят форматиращия механизъм, за да не се налага зареждането на всеки ред в паметта. Това са подходящите режими за заявки от типа „колко“ и „къде“.
Паралелни сканирания
Подайте -j N, за да разпределите сканирането между N работни процеса. Greph използва pcntl_fork() за пула от работни процеси и преминава към изпълнение в един процес, когато ext-pcntl не е налично.
./vendor/bin/greph -F -j 8 "function" src
Фасадата изчислява дали паралелното изпълнение си заслужава допълнителните разходи въз основа на броя файлове, режима и формата на шаблона. Под прага остава в един процес. Вижте Разширени настройки / Паралелни работни процеси за евристиките.
Изход във формат JSON
--json извежда структурирани данни, които следващите инструменти могат да обработят, без да извличат данни от екрана във формата на 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": []
}
]
}
]
Обвивката rg вместо това извежда JSON във формат на събития ripgrep. Използвайте я, когато съществуващ потребител очаква схемата ripgrep.
Програмно използване
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";
}
}
Обектите с резултати са описани в API / Обекти с резултати.
Как работи
Текстовият енджин има два пътя:
- Буквален път: когато е зададено
-F, търсенето се изпълнява сstrpos()върху буфериран четец с размер 64 KiB и се следят новите редове за номериране на редовете. Компилиране на регулярни изрази не се извършва. - Път с регулярни изрази: когато
-Fне е зададено, Greph извлича буквални поднизове от шаблона чрез малък анализатор в стил PCRE (Greph\Text\LiteralExtractor) и ги използва като предварителен филтърstrpos(). След това редовете, преминали предварителния филтър, се проверяват спрямо компилирания шаблон PCRE2 с активиран JIT.
И двата пътя използват един и същ BufferedReader за входно-изходните операции. Четецът чете на блокове от 64 KiB вместо fgets() на ред, което драстично намалява броя системни извиквания при големи файлове.
При повтарящи се задачи индексираният текстов режим заменя буферирания четец с предварително заредено хранилище за триграми и публикации на идентификатори и пропуска повечето файлове изцяло.