البرمجة

التعابير النمطية في جافاسكريبت

التعابير النمطية (Regular Expressions) في جافاسكريبت: شرح شامل وموسع

تعتبر التعابير النمطية أو الـ Regular Expressions في جافاسكريبت من الأدوات القوية والمرنة التي تمكّن المطورين من التعامل مع النصوص بطريقة متقدمة، سواء كان ذلك في البحث عن أنماط معينة داخل النصوص، التحقق من صحة البيانات، أو حتى تعديل النصوص بناءً على قواعد محددة. إن فهم هذه التقنية بشكل متعمق يفتح آفاقاً واسعة أمام البرمجة النصية في جافاسكريبت، ويساعد على تحسين جودة البرامج وتسهيل عمليات المعالجة النصية المعقدة.

في هذا المقال الموسع، سوف نناقش التعابير النمطية في جافاسكريبت من كافة جوانبها، بدءًا من المفاهيم الأساسية، مرورًا بالبناء والتركيب، وصولاً إلى الاستخدامات المتقدمة، مع شرح دقيق للأمثلة والوظائف المتوفرة في لغة جافاسكريبت. كما سنتطرق إلى أفضل الممارسات في تصميم التعابير النمطية وتحليل أدائها.


تعريف التعابير النمطية

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

في جافاسكريبت، يتم تمثيل التعابير النمطية بواسطة كائنات من نوع RegExp، وهناك طريقتان أساسيتان لتعريف تعبير نمطي:

  1. التعريف باستخدام القوسين المائلين /pattern/flags

  2. التعريف باستخدام كائن RegExp عبر المنشئ new RegExp("pattern", "flags")


بناء التعابير النمطية

1. الصيغة الأساسية

مثال على تعريف تعبير نمطي يبحث عن كلمة “hello”:

js
const regex = /hello/;

يمكن أيضًا كتابة نفس التعبير باستخدام منشئ RegExp:

js
const regex = new RegExp("hello");

2. الأعلام (Flags)

الأعلام هي خيارات إضافية تُضاف بعد نهاية التعبير النمطي لتغيير طريقة البحث، أشهر الأعلام هي:

  • g: البحث بشكل شامل (Global)، أي البحث عن كل المطابقات وليس الأولى فقط.

  • i: البحث بدون مراعاة حالة الحروف (Insensitive).

  • m: البحث متعدد الأسطر (Multi-line)، يسمح للتعبير بالتعامل مع النصوص متعددة الأسطر بشكل مختلف.

  • s: نمط النقطة يشمل الأسطر الجديدة (dotAll)، تسمح للنقطة . بمطابقة أي حرف بما في ذلك نهاية السطر.

  • u: يفعّل دعم الرموز متعددة البايت (Unicode).

  • y: البحث المتعلق بالموضع (Sticky)، يبدأ البحث من موقع محدد في النص ولا يتخطاه.

3. الأحرف الخاصة (Metacharacters)

تحتوي التعابير النمطية على مجموعة من الأحرف الخاصة التي تؤدي وظائف معينة، منها:

الحرف الوصف
. تطابق أي حرف ما عدا نهاية السطر
\d تطابق أي رقم (0-9)
\D تطابق أي حرف ليس رقمًا
\w تطابق أي حرف أبجدي رقمي أو underscore (_)
\W تطابق أي حرف ليس أبجدي رقمي
\s تطابق أي حرف فراغ (مسافة، تاب، إلخ)
\S تطابق أي حرف ليس فراغًا
^ بداية السلسلة أو بداية السطر في الوضع متعدد الأسطر
$ نهاية السلسلة أو نهاية السطر
* تطابق الصفر أو أكثر من العنصر السابق
+ تطابق واحد أو أكثر من العنصر السابق
? تطابق صفر أو واحد من العنصر السابق
{n} تطابق العنصر السابق تمامًا n مرات
{n,} تطابق العنصر السابق n مرات أو أكثر
{n,m} تطابق العنصر السابق بين n و m مرات
[...] مجموعة تطابق أي حرف بداخل الأقواس
[^...] مجموعة تطابق أي حرف ليس بداخل الأقواس
` `
() تحديد مجموعة وتخزين نتيجة المطابقة (Capturing group)

الأمثلة العملية على التعابير النمطية

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

مثال تعبير نمطي للتحقق من صحة البريد الإلكتروني البسيط:

js
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

هذا التعبير يشرح أنه يجب أن يبدأ بـ:

  • حروف أو أرقام أو بعض الرموز مثل النقطة أو الشرطة السفلية.

  • يتبعها علامة @.

  • ثم نطاق يتكون من حروف وأرقام ونقاط.

  • وأخيرًا نطاق علوي (مثل .com أو .net) مكون من حرفين أو أكثر.


البحث عن أرقام الهاتف

تعبير نمطي لأرقام الهاتف بصيغة معينة (مثال دولي يبدأ بـ + ثم أرقام):

js
const phoneRegex = /^\+\d{1,3}[- ]?\d{6,14}$/;

يفسر كالتالي:

  • يبدأ بعلامة +.

  • يتبعها من 1 إلى 3 أرقام.

  • مسافة أو شرطة اختيارية.

  • ثم رقم مكون من 6 إلى 14 رقم.


استخراج الكلمات من نص

للحصول على كل الكلمات التي تتكون من حروف فقط من نص معين:

js
const words = text.match(/\b[a-zA-Z]+\b/g);

\b تعني حدود الكلمة، مما يضمن أن الكلمات تُلتقط كاملة دون أجزاء.


استخدام الدوال المدمجة مع التعابير النمطية في جافاسكريبت

توفر جافاسكريبت عدة دوال ومناهج تساعد في التعامل مع التعابير النمطية على النصوص، منها:

1. test()

تُستخدم لفحص وجود نمط معين داخل نص ما، وتُعيد قيمة منطقية true أو false.

js
const regex = /world/; console.log(regex.test("Hello world!")); // true

2. exec()

تُستخدم للبحث عن تطابق واحد أو أكثر في النص، وتعيد مصفوفة تحتوي على المعلومات حول المطابقة، أو null إذا لم توجد تطابقات.

js
const regex = /world/; const result = regex.exec("Hello world!"); console.log(result[0]); // "world"

3. match()

تُستخدم على النصوص للبحث عن تطابقات التعبير النمطي، تعيد مصفوفة تحتوي على المطابقات.

js
const text = "The rain in SPAIN stays mainly in the plain"; const matches = text.match(/ain/g); console.log(matches); // ["ain", "ain", "ain"]

4. replace()

تُستخدم لاستبدال أجزاء من النص بناءً على نمط تعبير نمطي معين.

js
const text = "Hello 123, this is 456"; const result = text.replace(/\d+/g, "#"); console.log(result); // "Hello #, this is #"

5. search()

تُستخدم لإيجاد أول موقع يتطابق مع التعبير النمطي.

js
const index = "hello world".search(/world/); console.log(index); // 6

6. split()

يمكن تقسيم النص إلى مصفوفة بناءً على نمط التعبير النمطي.

js
const csv = "apple,banana,orange"; const fruits = csv.split(/,/); console.log(fruits); // ["apple", "banana", "orange"]

المجموعات والتقاط النصوص (Capturing Groups)

تُستخدم الأقواس () في التعبير النمطي لتجميع أجزاء من النمط ولقبض نتائج تطابقها لتتم معالجتها لاحقًا. يمكن استخدام هذه المجموعات لاستبدال النصوص أو استخراج أجزاء محددة.

مثال:

js
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/; const text = "2024-05-19"; const result = dateRegex.exec(text); console.log(result[0]); // "2024-05-19" — النص المطابق كاملًا console.log(result[1]); // "2024" — المجموعة الأولى (السنة) console.log(result[2]); // "05" — المجموعة الثانية (الشهر) console.log(result[3]); // "19" — المجموعة الثالثة (اليوم)

التعابير النمطية غير الطماعة (Non-Greedy vs Greedy Matching)

عند استخدام الكميات مثل * أو + فإنها بشكل افتراضي تطابق أكبر عدد ممكن من الأحرف (طماعة – Greedy). يمكن جعلها تطابق أقل عدد ممكن باستخدام ? بعد هذه الكميات.

مثال:

js
const greedy = /<.*>/; const nonGreedy = /<.*?>/; const text = "
Content
"
; console.log(text.match(greedy)[0]); // "
Content
"
console.log(text.match(nonGreedy)[0]); // "
"

استخدام التعابير النمطية في التحقق من صحة المدخلات

تُستخدم التعابير النمطية بكثرة في التحقق من صحة بيانات المستخدم في النماذج، مثل:

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

  • التحقق من أرقام الهواتف.

  • التحقق من كلمات المرور (وجود أحرف كبيرة وصغيرة وأرقام ورموز).

  • التحقق من تنسيقات التواريخ.

مثال للتحقق من كلمة مرور قوية:

js
const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$/;

هذا التعبير يضمن وجود:

  • حرف صغير واحد على الأقل.

  • حرف كبير واحد على الأقل.

  • رقم واحد على الأقل.

  • رمز خاص واحد على الأقل.

  • الطول لا يقل عن 8 أحرف.


الأداء والاعتبارات الخاصة بالتعابير النمطية

رغم قوة التعابير النمطية، إلا أن سوء استخدامها قد يؤدي إلى مشاكل في الأداء، خاصةً مع تعابير نمطية معقدة أو مكتوبة بطريقة تسبب ما يسمى “الطمع الزائد” (Catastrophic Backtracking) الذي قد يجعل عملية البحث تستغرق وقتاً طويلاً.

لذلك من الضروري:

  • كتابة التعبير النمطي بطريقة واضحة ومدروسة.

  • تجنب التعابير التي تحتوي على كميات متداخلة بدون حدود واضحة.

  • اختبار التعبير النمطي على بيانات حقيقية ومتنوعة.

  • الاستفادة من أدوات تحليل التعابير النمطية المتوفرة عبر الإنترنت لاكتشاف المشاكل وتحسين التعبير.


مقارنة بين الأساليب المختلفة لتعريف التعابير النمطية

التعريف الاستخدام المزايا العيوب
/pattern/flags التعبير النمطي الثابت داخل الكود أكثر وضوحًا وأسهل قراءة، أسرع أداء لا يدعم بناء التعبير ديناميكيًا
new RegExp("pattern", "flags") التعبير النمطي ديناميكيًا (كلمات متغيرة) يمكن إنشاء تعبير نمطي من متغيرات نصية يجب الانتباه إلى الهروب من الأحرف الخاصة

التعامل مع الأحرف الخاصة والهروب (Escaping)

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

مثال:

js
const regex = /\./; // يبحث عن نقطة فعلية في النص

خاتمة

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

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


المصادر والمراجع