コンテンツへスキップ

テキスト検索

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
JSON
[
  {
    "file": "src/Greph.php",
    "matches": [
      {
        "line": 31,
        "column": 1,
        "content": "final class Greph",
        "matched_text": "function",
        "captures": []
      }
    ]
  }
]

rgラッパーは、代わりにripgrepイベント形式のJSONを出力します。既存の利用側が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 / Result objects]を参照してください。

仕組み

テキストエンジンには2つの処理経路があります。

  • リテラル経路:-Fを設定すると、64 KiBのバッファ付きリーダーでstrpos()を実行し、行番号を追跡するために改行を記録します。正規表現のコンパイル処理はありません。
  • 正規表現経路:-Fを設定していない場合、Grephは小規模なPCRE形式の解析器(Greph\Text\LiteralExtractor)を使ってパターンからリテラル部分文字列を抽出し、strpos()の事前フィルターとして使用します。事前フィルターを通過した行は、JITを有効にしてコンパイルしたPCRE2パターンと照合されます。

どちらの経路も、I/Oには同じBufferedReaderを使用します。リーダーはfgets()単位ではなく64 KiB単位で読み込むため、大きなファイルではシステムコール数が大幅に減少します。

繰り返し実行するワークロードでは、インデックス付きテキストモード]がバッファ付きリーダーの代わりに、ウォームアップ済みのトライグラム+識別子ポスティングストアを使うため、ほとんどのファイルを丸ごとスキップできます。