Към съдържанието

Търсене в текст

Текстовият режим на 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
JSON
[
  {
    "file": "src/Greph.php",
    "matches": [
      {
        "line": 31,
        "column": 1,
        "content": "final class Greph",
        "matched_text": "function",
        "captures": []
      }
    ]
  }
]

Обвивката rg вместо това извежда JSON във формат на събития ripgrep. Използвайте я, когато съществуващ потребител очаква схемата ripgrep.

Програмно използване

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

Обектите с резултати са описани в API / Обекти с резултати.

Как работи

Текстовият енджин има два пътя:

  • Буквален път: когато е зададено -F, търсенето се изпълнява с strpos() върху буфериран четец с размер 64 KiB и се следят новите редове за номериране на редовете. Компилиране на регулярни изрази не се извършва.
  • Път с регулярни изрази: когато -F не е зададено, Greph извлича буквални поднизове от шаблона чрез малък анализатор в стил PCRE (Greph\Text\LiteralExtractor) и ги използва като предварителен филтър strpos(). След това редовете, преминали предварителния филтър, се проверяват спрямо компилирания шаблон PCRE2 с активиран JIT.

И двата пътя използват един и същ BufferedReader за входно-изходните операции. Четецът чете на блокове от 64 KiB вместо fgets() на ред, което драстично намалява броя системни извиквания при големи файлове.

При повтарящи се задачи индексираният текстов режим заменя буферирания четец с предварително заредено хранилище за триграми и публикации на идентификатори и пропуска повечето файлове изцяло.