Текстовий пошук
Текстовий режим 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 забезпечують роботу рушія, тож синтаксис відповідає офіційній довідці PCREPHP.
Вимкніть рушій регулярних виразів за допомогою -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 / Фільтрі типів файлів.
Контекст, підрахунок і режими лише для файлів
# 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() для кожного рядка, що різко зменшує кількість системних викликів у великих файлах.
Для повторюваних завдань індексований текстовий режим замінює буферизований зчитувач прогрітим сховищем триграм і індексом ідентифікаторів, пропускаючи більшість файлів.