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

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

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

ابدأ الدورة

التعبيرات المنتظمة في C++: أداة قوية للعمل مع النصوص



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



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



تتضمن مكتبة <regex> عدة فئات ووظائف رئيسية:



  • std::regex — فئة تمثل تعبيرًا منتظمًا مُجمّعًا.
  • std::smatch — حاوية لتخزين نتائج البحث (للسلاسل النصية من نوع std::string).
  • std::regex_match — تتحقق مما إذا كانت السلسلة النصية بأكملها تطابق النمط.
  • std::regex_search — تبحث عن أول ظهور للنمط في السلسلة النصية.
  • std::regex_replace — تستبدل التطابقات بالنص المحدد.


دعنا نستعرض كلًا من هذه المكونات من خلال الأمثلة.



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



تُرجع الدالة std::regex_match القيمة true إذا كانت السلسلة النصية بأكملها تطابق التعبير المنتظم تمامًا. هذا مثالي للتحقق من صحة البيانات، مثل التحقق من البريد الإلكتروني أو رقم الهاتف.



#include <iostream>#include <regex>#include <string>

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


في هذا المثال، استخدمنا السلسلة النصية الخام R"(...)" لتجنب الهروب من الخطوط المائلة العكسية. يتحقق النمط من أن السلسلة تحتوي على الجزء المحلي، وعلامة @، واسم النطاق، ونطاق المستوى الأعلى.



مثال 2: البحث عن سلسلة فرعية في النص (regex_search)



إذا كنت بحاجة إلى العثور على أول ظهور لنمط داخل سلسلة نصية، يتم استخدام std::regex_search. يتم حفظ النتائج في كائن std::smatch.



#include <iostream>#include <regex>#include <string>

int main() { std::string text = "رقم هاتفي: +7 (123) 456-78-90. اتصل بي!"; // نمط للبحث عن رقم هاتف روسي std::regex phone_pattern(R"(\\+7\\s?\\(?\\d{3}\\)?\\s?\\d{3}[- ]?\\d{2}[- ]?\\d{2})"); std::smatch match; if (std::regex_search(text, match, phone_pattern)) { std::cout << "تم العثور على الرقم: " << match.str() << std::endl; std::cout << "الموضع: " << match.position() << std::endl; } else { std::cout << "لم يتم العثور على الرقم." << std::endl; } return 0;}


لا يحتوي كائن match على السلسلة النصية التي تم العثور عليها فحسب، بل يحتوي أيضًا على معلومات حول موضع التطابق. يقوم الأسلوب match.str() بإرجاع الجزء الذي تم العثور عليه، بينما يقوم match.position() بإرجاع فهرس بداية التطابق في السلسلة النصية الأصلية.



مثال 3: استبدال النص باستخدام regex_replace



تقوم الدالة std::regex_replace باستبدال جميع تكرارات النمط بالسلسلة النصية المحددة. يمكن استخدام المراجع الخلفية (backrefer

المدونات

توصيات الكتب