التعبير النمطي (Regex) طريقة مختصرة لوصف نمط نصي: ليس سلسلة معينة، بل قاعدة يجب أن تحققها السلسلة. بدلاً من المرور على الأحرف في حلقة، يمكنك التحقق من بنية معقدة أو إيجادها بتعبير واحد.
اللبنات الأساسية
- فئات الأحرف —
\d(رقم)،\w(حرف/رقم/شرطة سفلية)،\s(مسافة)، أو فئة مخصصة مثل[a-zA-Z]. - المكمّمات —
*(صفر أو أكثر)،+(واحد أو أكثر)،?(صفر أو واحد)،{2,5}(من 2 إلى 5 مرات). - مجموعات الالتقاط — الأقواس
(...)تحدد جزءًا من نتيجة المطابقة يمكن استخدامه لاحقًا بشكل منفصل، مثلاً في الاستبدال. - المرساة —
^و$تربط النمط ببداية أو نهاية السطر.
لماذا لا يطابق \w الأحرف العربية
في محرك التعبيرات النمطية الخاص بـ JavaScript الذي تعمل عليه هذه الأداة، يعني \w دائمًا [A-Za-z0-9_] فقط — أي الأحرف اللاتينية والأرقام والشرطة السفلية. لذلك يعطي /^\w+$/.test('مرحبا') النتيجة false، وإضافة العلَم u لا تغيّر شيئًا، لأن \w في JS يبقى مرتبطًا بمجموعة ASCII بغض النظر عن الأعلام المفعّلة. الصياغة الصحيحة لمطابقة نص عربي هي /^\p{L}+$/u — فئة "أي حرف" المبنية على خصائص Unicode، والمتاحة فقط مع العلَم u. يُلاحظ أيضًا أن علامات التشكيل العربية (مثل الفتحة والضمة) تُصنَّف كـ Mark لا Letter، فقد تحتاج أحيانًا [\p{L}\p{M}] لالتقاطها معًا.
المطابقة الجشعة مقابل الكسولة
افتراضيًا، المكمّمات "جشعة" — تحاول التقاط أكبر عدد ممكن من الأحرف، ولا تتراجع إلا إذا منع ذلك المطابقة. مثلاً، <.+> على <a>نص</a> سيلتقط كل شيء من أول < إلى آخر >. إضافة ? بعد المكمّم (<.+?>) يجعله "كسولاً" — يلتقط أقل ما يمكن، ويتوقف عند أول مطابقة صالحة.
لماذا نحتاج هذا
- التحقق من صيغة بيانات الإدخال (البريد الإلكتروني، رقم الهاتف، الرمز البريدي).
- البحث والاستبدال الجماعي بناءً على نمط، لا مطابقة دقيقة.
- استخراج بيانات منظّمة من سجلات أو نصوص غير منظّمة.
التراجع الكارثي (catastrophic backtracking)
المكمّمات المتداخلة مثل (a+)+ قد تجبر محرك التعبيرات النمطية، على مدخلات معينة، على تجربة عدد أُسّي من التوليفات قبل أن يقرر عدم وجود تطابق — فتتجمد الصفحة أو الخادم على تعبير يبدو بسيطًا. هذه ثغرة حقيقية (ReDoS)، لذا يجدر اختبار المكمّمات المتداخلة المعقدة على سلاسل طويلة "شبه متطابقة"، لا على الأمثلة المتوقعة فقط.