ما هو Regex؟ ولماذا يحتاج إلى تعامل خاصّ مع العربية؟
التعبير النمطيّ (Regular Expression أو اختصاراً Regex) لغة صغيرة جدّاً لوصف أنماط داخل النصوص. سطر واحد منها قد يستبدل عشرات الأسطر البرمجيّة: استخراج كلّ بريد إلكترونيّ من ملف، تحقّق من صيغة رقم جوّال سعوديّ، تنظيف رموز غير مرغوب فيها، أو تقسيم وثيقة طويلة على الجمل. لذلك كلّ محرّر أكواد، وكلّ لغة برمجة، وكلّ أداة معالجة نصوص تدعمها — من Excel و Notepad++ إلى Python و JavaScript.
المشكلة أنّ Regex وُلد في عالم ASCII، حيث كلّ حرف هو بايت واحد. ثمّ جاء Unicode بمئات الآلاف من الرموز، ومنها العربية بأشكالها المختلفة: الحرف الأساسيّ، أشكاله الأربعة (مفرد، أوّل، وسط، آخر)، التشكيل، الأرقام العربية-الهنديّة، المدّ، الهمزات، التطويل (ـ)، وأكثر. هذا يجعل أنماطاً تبدو بسيطة بالإنجليزيّة — مثل [a-z] — معقّدةً عند الانتقال إلى العربية، لأنّك تحتاج إلى التفكير في النطاقات Unicode الصحيحة، وفي ما إذا كان النصّ مطبَّعاً (normalized) قبل الاختبار أم لا.
نطاقات Unicode الأساسيّة للعربية
العربية موزَّعة في Unicode على عدّة كتل (blocks). أهمّها — وهي التي ستحتاجها في 95% من الحالات — كتلة Arabic من U+0600 إلى U+06FF. تشمل: الحروف الأساسيّة (ا، ب، ت، ث ...)، الهمزات (أ، إ، ئ، ؤ)، التشكيل، الأرقام العربية-الهنديّة (0-9)، وعلامات الترقيم العربية (؟، ،، ؛).
إذا أردت مطابقة أيّ حرف عربيّ — مع التشكيل والأرقام والعلامات — اكتب [\u0600-\u06FF] مع flag u (Unicode). أمّا إذا أردت الحروف فقط دون التشكيل، فاستثنِ نطاق التشكيل: [\u0621-\u064A]. وإذا احتجت إلى الأرقام العربية-الهنديّة فقط، فاستخدم [\u0660-\u0669].
هناك كتل إضافيّة قد تظهر في نصوص فارسيّة أو أوردويّة: Arabic Supplement (U+0750–U+077F)، Arabic Extended-A (U+08A0–U+08FF)، و Arabic Presentation Forms-A/B (U+FB50–U+FDFF و U+FE70–U+FEFF) للأشكال المركّبة الجاهزة. إن كنت تعمل على نصّ مختلط أو على PDFs محوَّلة، قد تصادف هذه الكتل — لذلك اجمعها في نمط واحد: [\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF].
الـ Flags وأثرها على النصّ العربيّ
الـ Flags هي مُعدِّلات تأتي بعد نهاية النمط (مثل /pattern/giu). ستّة منها تهمّك:
g (global): يعيد كلّ المطابقات لا الأولى فقط. ضروريّ عند الاستخراج أو الاستبدال الشامل.
i (ignore case): لا أثر له على العربية لأنّها بلا أحرف كبيرة وصغيرة. مفيد فقط للنصّ المختلط الإنجليزيّ-العربيّ.
m (multiline): يجعل ^ و $ تطابقان بداية ونهاية كلّ سطر بدلاً من بداية ونهاية النصّ كلّه. مهمّ لمعالجة قوائم سطر-سطر.
s (dotall): يجعل النقطة . تطابق حتّى السطر الجديد. مفيد عند التقاط فقرات تمتدّ عبر أسطر.
u (unicode): الأهمّ بالنسبة لنا. يُفعِّل دعم Unicode الكامل، ويسمح بكتابة \u{1F600} للرموز فوق U+FFFF (الإيموجي مثلاً). بدونه قد تتصرّف نطاقاتك بشكل غير متوقَّع. القاعدة: أضِف u دائماً عند العمل بالعربية.
y (sticky): يبدأ المطابقة من lastIndex بالضبط دون القفز. متقدِّم، نادراً ما تحتاجه يدويّاً.
مأزق التشكيل (Diacritics)
أكثر خطأ يقع فيه المبتدئون: نمط يعمل في الاختبار ثمّ يفشل في الإنتاج، لأنّ النصّ الإنتاجيّ يحتوي على تشكيل لم يحسبه. مثلاً نمط محمد لن يطابق مُحَمَّد لأنّ كلّ ضمّة وفتحة وشدّة بينهما حرفٌ Unicode مستقلّ (في النطاق U+064B–U+0652، إضافةً إلى الألف الخنجريّة U+0670).
الحلّ في طبقتين: طبِّع النصّ قبل المطابقة بإزالة التشكيل (راجع أداة أداة تطبيع النصّ العربيّ في القائمة)، أو اكتب النمط نفسه ليتسامح مع التشكيل بين الحروف. الثانية تبدو هكذا: م[\u064B-\u0652\u0670]*ح[\u064B-\u0652\u0670]*م[\u064B-\u0652\u0670]*د. قبيحة، لكنّها تعمل. لذلك يُفضَّل دائماً التطبيع المسبق.
الأرقام: عربية شرقيّة، عربية غربيّة، وحالات مختلطة
الأرقام التي نكتبها يوميّاً (1, 2, 3) تُسمّى تقنيّاً "أرقام عربية غربيّة" وهي في نطاق ASCII العاديّ [0-9]. أمّا الأرقام التي تستخدمها بعض الواجهات والوثائق الرسميّة (0، 1، 2 ...) فهي "عربية-هنديّة شرقيّة" في نطاق [\u0660-\u0669]. والأرقام الفارسيّة (0، 1، 2 ...) في نطاق ثالث [\u06F0-\u06F9].
إذا أردت مطابقة رقم بصرف النظر عن صيغته، اجمع الثلاثة: [0-9\u0660-\u0669\u06F0-\u06F9]+. هذا مهمّ بشكل خاصّ في التحقّق من أرقام الجوّال وأرقام الهويّة الوطنيّة والبيانات الماليّة، حيث قد يكتب المستخدم نفس الرقم بصيغتين مختلفتين.
أنماط جاهزة شائعة
بريد إلكترونيّ مبسَّط: [\w.+-]+@[\w-]+\.[\w.-]+. ليست RFC-compliant لكنّها كافية لـ 99% من الحالات الواقعيّة.
رقم جوّال سعوديّ: (?:\+966|0)5\d{8}. يقبل الصيغتين +966 و 05. إذا أردت دعم الأرقام العربية-الهنديّة أيضاً، استبدل \d بـ [0-9\u0660-\u0669].
IBAN سعوديّ: SA\d{22}. التحقّق الكامل يحتاج إلى MOD-97 فلا يتمّ بـ Regex وحده، لكنّ هذا النمط يستبعد 99% من الإدخالات الخاطئة.
تاريخ ISO: \d{4}-\d{2}-\d{2}. يطابق 2026-05-18 لكن لا يتحقّق منطقيّاً (سيقبل 2026-13-45). للتحقّق المنطقيّ استخدم مكتبة تواريخ.
كلمات عربية فقط: [\u0621-\u064A]+ مع flag u. مفيد لاستخراج المحتوى العربيّ من نصّ مختلط.
إزالة المسافات المتعدّدة: استبدل \s{2,} بمسافة واحدة. ينظِّف النصوص المنسوخة من PDFs.
Capture Groups وما يمكنك فعله بها
القوسان () لا يجمعان جزءاً من النمط فحسب، بل يلتقطانه أيضاً ليصبح متاحاً للاستبدال أو الاستخراج. مثلاً النمط (\d{4})-(\d{2})-(\d{2}) يلتقط السنة والشهر واليوم في ثلاث مجموعات. في الاستبدال، استخدمها بـ $1 و $2 و $3 لإعادة ترتيب التاريخ مثلاً إلى صيغة DD/MM/YYYY: استبدل بـ $3/$2/$1.
إن كنت تريد التجميع دون الالتقاط (لتحسين الأداء)، استخدم (?:...). وإن أردت مجموعات بأسماء، استخدم (?<year>\d{4}) ثمّ ارجع لها بـ $<year>. هذا أوضح بكثير من الأرقام في الأنماط الطويلة.
Lookahead و Lookbehind: المطابقة المشروطة
أحياناً تريد مطابقة شيء فقط إذا سبقه أو لحقه شيء آخر — دون أن يكون ذاك "الآخر" جزءاً من النتيجة. هنا تأتي الـ Lookarounds:
Positive Lookahead (?=...): "متبوع بـ". مثال: \d+(?=\s*ريال) يلتقط الأرقام التي يليها كلمة "ريال" دون أن يلتقط الكلمة نفسها.
Negative Lookahead (?!...): "غير متبوع بـ". مثال: \d+(?!%) يلتقط الأرقام التي لا يليها علامة %.
Positive Lookbehind (?<=...): "مسبوق بـ". مثال: (?<=\$)\d+ يلتقط الأرقام التي يسبقها $ دون أن يلتقط الرمز.
Negative Lookbehind (?<!...): "غير مسبوق بـ". مثال: (?<!\.)\d+ يلتقط الأرقام التي لا تكون جزءاً من عدد عشريّ.
أخطاء شائعة تكلّفك ساعات
الجشع (Greedy) مقابل الكسل (Lazy): الكمّيات مثل + و * جشعةٌ افتراضيّاً — تحاول التهام أكبر نصّ ممكن. النمط <.+> على <b>مرحباً</b> يطابق كلّ السلسلة لا الوسم الأوّل فقط. أضف ? لجعلها كسولة: <.+?>.
هروب الرموز الخاصّة: النقطة . تعني "أيّ حرف" لا النقطة الحرفيّة. لمطابقة نقطة حقيقيّة اكتب \.. القاعدة نفسها تنطبق على: * + ? ( ) [ ] { } ^ $ | \ /.
نسيان flag g: String.replace بدون g يستبدل أوّل مطابقة فقط. إذا أردت استبدال الكلّ، أضف g.
Catastrophic Backtracking: أنماط مثل (a+)+b على نصّ طويل من حروف a دون b قد تجمِّد المتصفِّح. إذا لاحظت بطئاً مفاجئاً، راجع تداخل الكمّيات.
الخلط بين النطاق والحرف: [a-z] نطاق من a إلى z. لكن [abc] ثلاثة أحرف فقط. ضع الشرطة في البداية أو النهاية لجعلها حرفيّة: [-abc] أو [abc-].
كيف تستخدم الأداة أعلاه
الأداة تعطيك أربعة مكوِّنات: (1) حقل النمط مع الـ Flags كأزرار تفاعليّة، (2) أنماط جاهزة بضغطة زرّ تشمل العربية والجوّال السعوديّ والتاريخ، (3) نصّ اختبار قابل للتعديل مع تلوين فوريّ للمطابقات، (4) جدول تفصيليّ لكلّ مطابقة (الموضع، الطول، النصّ).
ابدأ من نمط جاهز قريب من حالتك ثمّ عدّله، ولاحظ كيف تتغيّر المطابقات الملوَّنة فوريّاً. إذا ظهر شريط أحمر، فالنمط غير صالح — اقرأ الرسالة لمعرفة الموقع. عندما يعمل النمط كما تريد، انقل النصّ /pattern/flags إلى كودك أو أداتك المفضّلة. كلّ شيء يجري في المتصفِّح، فلا يخرج النصّ أو النمط من جهازك.
ReDoS: حين يَتحوّل النمط إلى ثغرة أمنيّة
أكثر فخّ يَقع فيه المطوّرون مع التعابير النمطيّة لا يَتعلّق بالصِّحّة بل بالأداء: نمط واحد سيّء قد يُجمِّد الخادم لثوانٍ أو دقائق عند إدخال مُعدّ خصّيصاً. هذا الهجوم اسمه ReDoS (Regular Expression Denial of Service)، و يَستغلّ ظاهرة catastrophic backtracking في المحرّكات التَّقليديّة (PCRE, Java, JavaScript V8).
- الأنماط الخطرة — كلّ ما يَحوي تَكراراً متداخلاً مثل
(a+)+أو(.*)*. عَدّ خطوات المحرّك يَنفجر أُسّيّاً مع طول الإدخال. - الكشف الآليّ — أدوات مثل
safe-regexأوregexploitتَفحص مستودعك و تُنبِّه عن الأنماط القابلة للاستغلال قبل النَّشر. - الحلّ المعماريّ — استبدِل المحرّك التَّقليديّ بـ
RE2من Google (يَدعمه Go أصلاً، و يُوجد ربط لـ Node و Python). RE2 يَضمن وقت تَنفيذ خطّيّاً على حساب بعض الميزات المتقدّمة (lookahead). - على حافة الـ CDN — Cloudflare Workers و AWS WAF يَستخدمان RE2 بشكل افتراضيّ. لو تَكتب قواعد WAF مخصّصة، تَأكَّد أنّك تَفهم القيود قبل نَسخ نمط من Stack Overflow.
نصيحة عمليّة للفِرَق السعوديّة التي تَبني APIs على Node.js أو NestJS: اعتبِر كلّ تَعبير نمطيّ يَستقبل مدخلاً من المستخدم بمثابة استعلام SQL — يَجب فحصه، اختباره، و وَضع حدّ أعلى لطول الإدخال (عادةً 1024 حرفاً يَكفي). أداة الاختبار هنا تُساعدك على بناء النمط، لكن قبل النَّشر شغِّله ضدّ سلاسل خبيثة (مثل aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!) و راقب الوقت.
أدوات ذات صلة
أدوات أخرى مجانية على ArabToolBox، كلها تعمل في متصفّحك بدون تسجيل.
- مولّد Cron Expressionsابنِ تعبيرات Cron بصرياً + شرح بالعربية
- مرجع HTTP Statusمرجع كامل لكل أكواد HTTP بالعربية + الأسباب
- مولّد robots.txtابنِ robots.txt يدعم AI Crawlers + احجب ما تريد
- ترميز URLترميز URL مع دعم كامل للأحرف العربية + Query Strings
- منسّق JSONتنسيق وتحقق JSON مع مقارنة Diff وتحويل لـ CSV/YAML
- مقارنة نصوص عربيةقارن نصّين عربيّين واكتشف الفروقات سطراً بسطر