التعبيرات النمطية في لغة C++ مع أمثلة: دليل عملي

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

التعبيرات النمطية في لغة C++ مع أمثلة: من الناحية العملية

\n\n

التعبيرات النمطية (regex) هي أداة قوية لمعالجة النصوص، تتيح البحث والاستبدال والتحقق من السلاسل النصية وفق أنماط معقدة. في لغة C++، ظهر دعم التعبيرات النمطية في المعيار C++11 من خلال المكتبة <regex>. في هذه المقالة، سنشرح كيفية استخدام std::regex عمليًا: من الفحوصات البسيطة إلى استخراج البيانات واستبدال النص.

\n\n

ستكون المادة مفيدة لكل من المبتدئين الذين يتعرفون على لغة C++ لأول مرة، والمطورين ذوي الخبرة الذين يرغبون في تحديث معرفتهم. سنستعرض الوظائف الرئيسية: std::regex_match و std::regex_search و std::regex_replace، بالإضافة إلى العمل مع مجموعات الالتقاط.

\n\n

المكونات الأساسية للمكتبة <regex>

\n\n

قبل الانتقال إلى الأمثلة، دعنا نفهم الفئات والوظائف الأساسية:

\n\n
    \n
  • std::regex — فئة تمثل التعبير النمطي نفسه (النمط). يتم إنشاؤها من سلسلة نصية تحتوي على النمط وعلامة اختيارية لقواعد اللغة (افتراضيًا ECMAScript).
  • \n
  • std::smatch — حاوية لتخزين نتائج البحث (للسلاسل النصية من نوع std::string). النظير هو std::cmatch للسلاسل النصية من نوع C.
  • \n
  • std::regex_match — تتحقق مما إذا كانت السلسلة النصية بأكملها تطابق النمط بالكامل.
  • \n
  • std::regex_search — تبحث عن سلسلة فرعية تطابق النمط في أي مكان داخل السلسلة النصية.
  • \n
  • std::regex_replace — تستبدل جميع التطابقات مع النمط بسلسلة نصية محددة (مع دعم المراجع العكسية).
  • \n
\n\n

جميع الوظائف تقبل علامات للتحكم في السلوك (على سبيل المثال، std::regex_constants::icase للبحث غير الحساس لحالة الأحرف).

\n\n

مثال 1: التحقق من تطابق سلسلة نصية مع نمط (std::regex_match)

\n\n

أبسط مهمة هي التحقق مما إذا كانت السلسلة النصية تطابق تنسيقًا معينًا. على سبيل المثال، دعنا نتحقق مما إذا كانت السلسلة النصية عنوان بريد إلكتروني صحيحًا (نسخة مبسطة):

\n\n
#include <iostream>\n#include <regex>\n#include <string>\n\nint main() {\n    std::string email = "user@example.com";\n    // نمط للتحقق من البريد الإلكتروني (مبسط)\n    std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})");\n\n    if (std::regex_match(email, pattern)) {\n        std::cout << "البريد الإلكتروني صحيح." << std::endl;\n    } else {\n        std::cout << "البريد الإلكتروني غير صحيح." << std::endl;\n    }\n\n    // التحقق من بريد إلكتروني غير صحيح\n    std::string bad_email = "user@.com";\n    if (std::regex_match(bad_email, pattern)) {\n        std::cout << "البريد الإلكتروني صحيح." << std::endl;\n    } else {\n        std::cout << "البريد الإلكتروني غير صحيح." << std::endl;\n    }\n\n    return 0;\n}
\n\n

المخرجات:

\n
البريد الإلكتروني صحيح.\nالبريد الإلكتروني غير صحيح.
\n\n

الشرح:

\n
    \n
  • نستخدم حرفية السلسلة النصية الخام R"(...)" لتجنب الهروب من الخطوط المائلة العكسية.
  • \n
  • الدالة std::regex_match ترجع true فقط إذا كانت السلسلة النصية بأكملها تطابق النمط تمامًا.
  • \n
  • النمط [a-zA-Z0-9._%+-]+ يعني "حرف واحد أو أكثر من المجموعة المحددة".
  • \n
\n\n

مثال 2: البحث عن سلسلة فرعية واستخراج البيانات (std::regex_search)

\n\n

غالبًا ما نحتاج ليس فقط إلى التحقق، بل إلى العثور على جميع تكرارات النمط واستخراج أجزاء من السلسلة النصية. لهذا نستخدم std::regex_search في حلقة. في المثال التالي، سنجد جميع أرقام الهواتف بالتنسيق +7-XXX-XXX-XX-XX في النص ونستخرج رمز المشغل:

\n\n
#include <iostream>\n#include <regex>\n#include <string>\n\nint main() {\n    std::string text = "جهات الاتصال: +7-495-123-45-67 و +7-916-987-65-43. رقم إضافي: +7-495-111-22-33.";\n    // النمط: +7-الرمز(3 أرقام)-... (مجموعات التقاط للرمز والباقي)\n    std::rege                

المدونات

توصيات الكتب