テキスト検索
Grephのテキストモードは、走査したファイルツリーを対象に、行単位でバイト列を検索します。これはgreph CLIとGreph::searchText()ファサードのデフォルトモードです。出力には、grep、ripgrep、およびほとんどのエディター連携機能が解析できる標準のfile:line:content形式を使用します。
すぐに試せる例
# 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正規表現として扱われます。PHPのpreg_*関数がエンジンを支えるため、構文はPHP PCREリファレンス]と一致します。
-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
ファサードは、ファイル数、モード、パターンの形状をもとに、並列実行のオーバーヘッドに見合うかどうかを判定します。しきい値を下回る場合は単一プロセスのまま実行します。判定方法についてはAdvanced / Parallel Workers]を参照してください。
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ラッパーは、代わりにripgrepイベント形式のJSONを出力します。既存の利用側が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 / Result objects]を参照してください。
仕組み
テキストエンジンには2つの処理経路があります。
- リテラル経路:
-Fを設定すると、64 KiBのバッファ付きリーダーでstrpos()を実行し、行番号を追跡するために改行を記録します。正規表現のコンパイル処理はありません。 - 正規表現経路:
-Fを設定していない場合、Grephは小規模なPCRE形式の解析器(Greph\Text\LiteralExtractor)を使ってパターンからリテラル部分文字列を抽出し、strpos()の事前フィルターとして使用します。事前フィルターを通過した行は、JITを有効にしてコンパイルしたPCRE2パターンと照合されます。
どちらの経路も、I/Oには同じBufferedReaderを使用します。リーダーはfgets()単位ではなく64 KiB単位で読み込むため、大きなファイルではシステムコール数が大幅に減少します。
繰り返し実行するワークロードでは、インデックス付きテキストモード]がバッファ付きリーダーの代わりに、ウォームアップ済みのトライグラム+識別子ポスティングストアを使うため、ほとんどのファイルを丸ごとスキップできます。