
# البحث في النصوص

وضع النص في Greph هو بحث بايتات موجّه حسب السطر ضمن شجرة ملفات يجري استعراضها. وهو الوضع الافتراضي لكل من `greph` CLI وواجهة `Greph::searchText()`. تستخدم المخرجات التنسيق القياسي `file:line:content` الذي تحلله grep وripgrep ومعظم تكاملات المحررات.

## أمثلة سريعة

```bash
# 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](https://www.php.net/manual/en/pcre.pattern.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` افتراضيًا، ويتخطى الملفات الثنائية (التي تُكتشف عبر بايتات null في أول 512 بايتًا)، ويحدد حجم الملف الأقصى بـ 10 MiB. يمكن ضبط الحدين عبر `WalkOptions`.

راجع [API / مرشح أنواع الملفات](https://greph.inline0.dev/ar/docs/api#grephwalkerfiletypefilter) للاطلاع على القائمة الكاملة للأسماء المستعارة للأنواع المضمنة.

## السياق والعدّ والأوضاع المقتصرة على الملفات

```bash
# 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` متاحًا.

```bash
./vendor/bin/greph -F -j 8 "function" src
```

تحسب الواجهة ما إذا كان التنفيذ المتوازي يستحق تكلفته الإضافية، استنادًا إلى عدد الملفات والوضع وشكل النمط. وتظل بعملية واحدة إذا كان العدد دون الحد. راجع [متقدم / العمال المتوازيون](https://greph.inline0.dev/ar/docs/advanced/parallel) للاطلاع على أساليب التقييم.

## مخرجات JSON

يصدر `--json` حمولة منظّمة تستطيع الأدوات اللاحقة تحليلها دون استخراج البيانات من تنسيق grep المعروض على الشاشة:

```bash
./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 / كائنات النتائج](https://greph.inline0.dev/ar/docs/api#result-objects) كائنات النتائج.

## طريقة العمل

لمحرّك النص مساران:

- **المسار الحرفي**: عند ضبط `-F`، يجري البحث `strpos()` باستخدام قارئ ذي مخزن مؤقت بسعة 64 KiB، مع تتبّع الأسطر لترقيمها. لا توجد خطوة لتجميع التعبير النمطي.
- **مسار التعبير النمطي**: عند عدم ضبط `-F`، يستخرج Greph مقاطع حرفية من النمط باستخدام محلّل صغير شبيه بـ PCRE (`Greph\Text\LiteralExtractor`)، ويستخدمها كمرشح مسبق `strpos()`. ثم تُطابق الأسطر التي تجتاز المرشح مع نمط PCRE2 المجمّع، مع تفعيل JIT.

يستخدم المساران `BufferedReader` نفسه لإجراء الإدخال والإخراج. يقرأ القارئ البيانات على دفعات بحجم 64 KiB بدلًا من `fgets()` لكل سطر، ما يقلل عدد استدعاءات النظام كثيرًا في الملفات الكبيرة.

في أحمال العمل المتكررة، يستبدل [وضع النص المفهرس](https://greph.inline0.dev/ar/docs/indexed/text) القارئ ذا المخزن المؤقت بمخزن منشورات ثلاثية الكلمات والمعرّفات، ويُعاد استخدامه بعد تهيئته، متجاوزًا معظم الملفات بالكامل.
