أنماط Regex الأساسية التي يجب على كل مطور حفظها

مرجع أنماط regex الشائعة يعرض كودا مع تمييز بناء مطابقة الأنماط على خلفية محرر داكنة

أنماط regex هي قوالب قابلة لإعادة الاستخدام تُطابق تسلسلات محددة من الأحرف داخل النصوص - فكّر فيها كأداة "بحث" فائقة القدرة تعمل في كل لغات البرمجة تقريبًا. سواء كنت تتحقق من صحة عنوان بريد إلكتروني، أو تنظّف رقم هاتف من نموذج، أو تحلّل ملف log، فإن مجموعة صغيرة من التعبيرات النمطية المختارة بعناية ستغطي 90% من احتياجاتك. هذا الدليل يجمع أكثر الأنماط عملية، ويشرح بالتفصيل ما يفعله كل منها، مع توضيح كيفية تكييفها لمشاريعك.

مراجعة سريعة لأساسيات صياغة Regex

قبل الغوص في الأنماط، إليك ورقة مرجعية سريعة للعناصر الأساسية التي ستتكرر كثيرًا. حتى لو سبق لك التعامل مع regex، فمن المفيد أن تجدها كلها في مكان واحد.

الرمز (Token) المعنى مثال على التطابق
. أي حرف عدا سطر جديد a.c يطابق abc و a1c
\d أي رقم (0-9) \d\d يطابق 42
\w حرف كلمة (أحرف، أرقام، شرطة سفلية) \w+ يطابق hello_world
\s مسافة بيضاء (مسافة، tab، سطر جديد) \s+ يطابق مسافات متعددة
^ / $ بداية / نهاية النص ^\d+$ يطابق 123 فقط
{n,m} بين n و m تكرار \d{2,4} يطابق من 12 إلى 1234
[abc] فئة أحرف - أي من a أو b أو c [aeiou] يطابق أي حرف علة
(?:...) مجموعة غير آسرة (non-capturing group) تجميع بدون حفظ مرجع خلفي (backreference)
(?=...) lookahead إيجابي يتحقق مما يلي دون استهلاكه

يُعدّ دليل التعبيرات النمطية في MDN Web Docs أفضل مرجع شامل لصياغة regex في JavaScript، وتنطبق معظم الأنماط الواردة أدناه مباشرة على Python و PHP و Java و Ruby مع اختلافات بسيطة في الأعلام.

التحقق من البريد الإلكتروني

البريد الإلكتروني هو الاستخدام الكلاسيكي لـ regex - وهو أيضًا الحالة التي يُخطئ فيها معظم المطورين بمحاولة التشدد الزائد. تقنيًا، تتيح مواصفة RFC 5322 عناوين مثل "very unusual"@example.com التي لا يتعامل معها أي regex تقريبًا. لاحتياجات التحقق من المدخلات في 99% من الحالات الواقعية، استخدم هذا النمط العملي:

^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$

ما يفعله كل جزء:

  • [a-zA-Z0-9._%+\-]+ - الجزء المحلي (قبل @)؛ يقبل النقاط وعلامات الجمع والشرطات والشرطات السفلية
  • @ - علامة @ الحرفية
  • [a-zA-Z0-9.\-]+ - اسم النطاق، بما في ذلك النطاقات الفرعية
  • \.[a-zA-Z]{2,} - امتداد النطاق (TLD) بحد أدنى حرفين (.io، .com، .museum)
لا يمكن لـ regex وحده التأكد من أن عنوان البريد الإلكتروني موجود فعلًا أو قابل للتسليم. أرسل دائمًا بريد تأكيد لأي شيء يستلزم ذلك.

عناوين URL والمواقع الإلكترونية

يغطي مطابقة أنماط URL كل شيء، من استخراج الروابط من النصوص العادية إلى التحقق من صحة حقل موقع ويب يُدخله المستخدم.

https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&\/=]*)
  • https? - يطابق كلًا من http و https
  • (?:www\.)? - بادئة www اختيارية
  • [-a-zA-Z0-9@:%._+~#=]{1,256} - أحرف اسم المضيف، بحد أقصى 256 حرفًا
  • \.[a-zA-Z0-9()]{1,6} - امتداد النطاق (TLD)
  • \b(?:[-a-zA-Z0-9()@:%_+.~#?&\/=]*) - المسار واستعلام البحث والمرساة (اختيارية)

إذا كنت تريد التحقق فقط (لا الاستخراج)، فأحط النمط بمرساتَي ^ و $ .

أرقام الهاتف

أرقام الهاتف معقدة بطبيعتها لأن تنسيقها يتفاوت بشكل كبير بحسب الدولة وعادات المستخدم. يغطي نمطان معظم السيناريوهات:

تنسيق الولايات المتحدة/كندا (NANP)

^(\+1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}$

يطابق: 555-867-5309 و (555) 867 5309 و +1.555.867.5309 و 5558675309

الدولي (تنسيق E.164)

^\+[1-9]\d{6,14}$

E.164 هو التنسيق الذي تستخدمه معظم telephony APIs (مثل Twilio و AWS SNS). يبدأ بـ + يليه رمز الدولة، بدون مسافات أو علامات ترقيم.

لأي شيء يتجاوز التحقق الأساسي من التنسيق - كالتحقق من أن الرقم خط جوال فعلي في دولة معينة - استخدم مكتبة متخصصة مثل libphonenumber (مكتبة Google مفتوحة المصدر لأرقام الهاتف، متاحة بـ Java و JavaScript و Python وغيرها).

التواريخ والأوقات

مطابقة أنماط التاريخ شائعة في محللات ملفات log، ومدققي النماذج، وخطوط معالجة البيانات. التنسيق الذي تستهدفه يعتمد على مصدر المدخلات.

ISO 8601 (YYYY-MM-DD)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

التنسيق الأمريكي (MM/DD/YYYY)

^(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/\d{4}$

الوقت بنظام 24 ساعة (HH:MM أو HH:MM:SS)

^([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?$

تجدر الإشارة إلى أن هذه الأنماط تتحقق من التنسيق فقط، لا من منطق التقويم. ستقبل مثلًا 2024-02-31 (الحادي والثلاثون من فبراير غير موجود). للتحقق الصارم من التاريخ، استخدم مكتبة التواريخ المتاحة في لغتك بعد فحص regex.

التحقق من قوة كلمة المرور

تتطلب قواعد كلمات المرور عادةً مزيجًا من أنواع الأحرف وحدًا أدنى للطول. يجعل lookahead هذا الأمر أنيقًا دون الحاجة إلى فحوصات منفصلة متعددة.

8 أحرف على الأقل، حرف كبير واحد على الأقل، وحرف صغير، ورقم

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$

قوية: 8 أحرف أو أكثر، حرف كبير وصغير ورقم وحرف خاص

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$

كل (?=.*[...]) هو lookahead يفحص النص بالكامل بحثًا عن حرف واحد مطابق على الأقل. يفرض .{8,} الأخير الحد الأدنى للطول. يمكنك استبدال {8,} بـ {12,} لفرض حد أدنى 12 حرفًا، وهو ما يتوافق مع إرشادات NIST SP 800-63B .

عناوين IP

IPv4

^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$

يرفض هذا النمط بشكل صحيح قيمًا مثل 999.0.0.1 عن طريق مطابقة كل octet صراحةً في النطاق 0-255.

IPv6 (مبسط)

^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$

يتعامل هذا النمط مع تنسيق المجموعات الثماني الكامل. بالنسبة للترميز المضغوط (مثل ::1 لعنوان loopback)، يصبح النمط أكثر تعقيدًا بكثير - في هذه الحالة، يكون التحليل باستخدام مكتبة شبكية أكثر موثوقية من regex.

HTML والترميز

بعض الأنماط المحددة مفيدة فعلًا هنا. لا تزال النصيحة العامة "لا تحلّل HTML بـ regex" سارية للمستندات الكاملة - استخدم محلل DOM مناسبًا مثل BeautifulSoup أو DOMParser لذلك. لكن للمهام المحددة والمحدودة، يعمل regex بشكل جيد.

إزالة جميع وسوم HTML

<[^>]*>

استخراج المحتوى من وسم محدد (مثل <title>)

([^<]*)<\/title>

تحتوي مجموعة الالتقاط الأولى على نص العنوان.

مطابقة أكواد الألوان السداسية عشرية في HTML

#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})\b

يطابق كلًا من الاختصار المكوّن من 3 أرقام ( #fff ) والشكل الكامل المكوّن من 6 أرقام ( #ffffff ).

أنماط الأدوات اليومية

هذه الأنماط تظهر باستمرار في مختلف أنواع المشاريع.

Slug (نص متوافق مع URL)

^[a-z0-9]+(?:-[a-z0-9]+)*$

يطابق نصوصًا مثل my-blog-post-2024 . بدون أحرف كبيرة، ولا شرطات في البداية أو النهاية، ولا شرطات متتالية.

رقم بطاقة الائتمان (تنسيق أساسي، بدون مسافات)

^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$
  • يبدأ بـ 4 - Visa (13 أو 16 رقمًا)
  • يبدأ بـ 51-55 - Mastercard (16 رقمًا)
  • يبدأ بـ 34 أو 37 - Amex (15 رقمًا)
  • يبدأ بـ 6011 أو 65 - Discover (16 رقمًا)
لا تخزّن أرقام البطاقات الخام أبدًا. هذا النمط مخصص لتغذية راجعة على التنسيق من جانب العميل فقط. يجب أن يمر التحقق الفعلي من البطاقة عبر معالج متوافق مع PCI مثل Stripe أو Braintree.

تطبيع المسافات البيضاء (تقليص المسافات المتعددة)

\s{2,}

استبدل التطابقات بمسافة واحدة لتنظيف مدخلات المستخدم الفوضوية أو النصوص المستخلصة.

أرقام فقط

^\d+$

أحرف وأرقام فقط

^[a-zA-Z0-9]+$

مطابقة سطر يحتوي على كلمة (غير حساس لحالة الأحرف مع علم)

^.*\bword\b.*$

حدّ الكلمة \b يمنع مطابقة word داخل password .

استخراج أرقام الإصدارات (semver)

\bv?(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.]+))?(?:\+([a-zA-Z0-9.]+))?\b

يلتقط الإصدار الرئيسي والثانوي والتصحيحي وتسمية الإصدار التجريبي وبيانات البناء من نصوص مثل v2.14.0-beta.1+build.42 .

الأعلام والنصائح العملية

تتصرف أنماط regex بشكل مختلف بحسب الأعلام المُطبَّقة. إليك الأكثر استخدامًا:

العلم JS Python التأثير
غير حساس لحالة الأحرف i re.IGNORECASE يعامل الأحرف الكبيرة والصغيرة كمتماثلة
عام (البحث عن الكل) g re.findall() يُرجع جميع التطابقات، لا الأول فقط
متعدد الأسطر m re.MULTILINE ^ و $ يطابقان حدود الأسطر لا حدود النص
Dotall s re.DOTALL . يطابق أحرف السطر الجديد أيضًا

بعض العادات التي ستوفر عليك وقت التنقيح:

  • اختبر دائمًا بحالات الحافة - النص الفارغ، الحد الأقصى للطول، أحرف Unicode، والنصوص التي تكاد تكون صحيحة لكنها ليست كذلك.
  • استخدم المجموعات غير الآسرة (?:...) عندما لا تحتاج إلى المحتوى المُطابَق - فهي أسرع وأنظف من مجموعات الالتقاط.
  • أرسِ أنماط التحقق بـ ^ و $ حتى لا تتسرب سلسلة نصية فرعية تبدو صحيحة داخل نص غير صحيح.
  • احذر من الbacktracking الكارثي - المحددات الكمية المتداخلة مثل (a+)+ قد تتسبب في تجميد محركات regex على مدخلات مصنوعة خصيصًا. أبقِ المحددات الكمية بسيطة ومحددة.
  • استخدم أداة اختبار regex أثناء بناء الأنماط. regex101.com تعرض تفصيلًا حيًا للتطابقات، وتشرح كل رمز، وتتيح التبديل بين PCRE و JavaScript و Python ونكهات أخرى.
أدوات مطابقة أنماط regex والتحقق من المدخلات

اختبر أنماط regex وتحقق منها بدون تخمين

بناء أنماط regex موثوقة للتحقق من المدخلات يكون أسرع حين تمتلك الأدوات الصحيحة. استكشف أدواتنا المجانية للمطورين لتنظيف النصوص وفحصها وتحويلها باستخدام أنماط regex وأكثر.

جرّب أدواتنا المجانية ←

المحددات الكمية الجشعة (مثل .* ) تطابق أكبر قدر ممكن ثم تتراجع. أما الكسولة (مثل .*? ) فتطابق أقل قدر ممكن. على سبيل المثال، مع النص bold ، يطابق النمط <.*> النص بالكامل، بينما يطابق <.*?> فقط . استخدم المحددات الكسولة عند استخراج محتوى بين محددات.

في الغالب نعم، لكن توجد فروق. وحدة re في Python تستخدم صياغة PCRE وتدعم المجموعات المسماة بـ (?P...) . يستخدم JavaScript صياغة أعلام مختلفة قليلًا ولا يدعم lookbehinds في المحركات القديمة (ما قبل ES2018). للعمل عبر لغات متعددة، التزم بالمجموعة المشتركة: فئات الأحرف، والمحددات الكمية، والمراسي، والمجموعات الأساسية.

regex مناسب تمامًا للتحقق من التنسيق في بيئة الإنتاج - يُستخدم في كل أطر العمل الويب تقريبًا. المخاطر تكمن في الأنماط المكتوبة بشكل سيئ التي تُتيح هجمات ReDoS (رفض الخدمة عبر regex) من خلال الbacktracking الكارثي. تجنب المحددات الكمية المتداخلة، وأبقِ الأنماط محددة، وضع دائمًا حدًا معقولًا لطول المدخلات قبل تشغيل regex.

في معظم المحركات الشائعة هما متكافئان لمدخلات ASCII. يظهر الفرق مع Unicode: \d في بعض المحركات (مثل Python 3 مع وضع Unicode) يطابق أرقامًا من خطوط كتابة أخرى، كالأرقام الهندية العربية. إذا أردت صراحةً أرقام ASCII من 0 إلى 9، استخدم [0-9] لتكون واضحًا. في معظم حالات التحقق من نماذج الويب، لا يهم هذا الفرق.

تحتاج إلى شيئين: علم dotall (حتى يطابق . أحرف السطر الجديد) وربما علم متعدد الأسطر (حتى ترتبط ^ و $ بكل سطر بدلًا من النص بأكمله). في JavaScript، استخدم /pattern/ms . في Python، ادمج re.DOTALL | re.MULTILINE . بدون dotall، يتوقف . عند فواصل الأسطر ولن يمتد نمطك عبر أسطر متعددة.