C++: التعابير النمطية

آخر تحديث: 2026-08-26

في الدرس 41، تعلمنا عن عمليات الملفات.

الآن، سنتعلم التعابير النمطية — "السكين السويسري" لمعالجة النصوص.

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


1. نظرة عامة على التعابير النمطية

(1) 1.1 ما هي التعابير النمطية؟

التعابير النمطية (Regex) هي لغة وصف أنماط النص تُستخدم لـ المطابقة، البحث، والاستبدال في النصوص.

تشبيه من الواقع:


(2) 1.2 مكتبة التعابير النمطية في C++

أضافت C++11 دعم التعابير النمطية في ملف الرأس regex.

أربع دوال رئيسية:

الدالة الغرض
std::regex_match مطابقة كاملة
std::regex_search بحث
std::regex_replace استبدال
std::regex_iterator بحث تكراري


2. المطابقة الأساسية

(1) 2.1 regex_match — المطابقة الكاملة

مثال: التحقق من رقم هاتف (الصعوبة ⭐)

▶ مثال 1: تطبيق التعابير النمطية (الصعوبة ⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <regex>
#include <string>

int main() {
	std::string phone = "13812345678";
	std::regex pattern("^1[3-9]\\d{9}$");
	
	if (std::regex_match(phone, pattern)) {
		std::cout << "Valid phone number" << std::endl;
	} else {
		std::cout << "Invalid phone number" << std::endl;
	}
	
	return 0;
}

الخرج:

TEXT 📖 للعرض فقط
Valid phone number
Invalid phone number

نتيجة التشغيل:

TEXT 📖 للعرض فقط
Valid phone number

(2) 2.2 صياغة التعابير النمطية

الرمز المعنى مثال
. أي حرف a.c يطابق abc
^ البداية ^abc يطابق السلاسل التي تبدأ بـ abc
$ النهاية abc$ يطابق السلاسل التي تنتهي بـ abc
* صفر أو أكثر a* يطابق aaa
+ واحد أو أكثر a+ يطابق aaa
? صفر أو واحد a? يطابق a أو ``
{n} بالضبط n مرة a{3} يطابق aaa
[abc] مجموعة أحرف [abc] يطابق a أو b أو c
[^abc] مجموعة مستبعدة [^abc] يطابق أي حرف ما عدا abc
\d رقم \d يطابق 0-9
\w حرف كلمة \w يطابق a-z، A-Z، 0-9، _


3. البحث والاستبدال

(1) 3.1 regex_search — البحث

مثال: البحث عن بريد إلكتروني (الصعوبة ⭐⭐)

CPP
#include <iostream>
### ▶ مثال 2: تطبيق التعابير النمطية (الصعوبة ⭐)

#include <regex>
#include <string>

int main() {
	std::string text = "Contact me:abc@example.com or test@gmail.com";
	std::regex pattern("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
	
	std::smatch match;
	if (std::regex_search(text, match, pattern)) {
		std::cout << "Found email: " << match[0] << std::endl;
	}
	
	return 0;
}

(2) 3.2 regex_replace — الاستبدال

مثال: إخفاء الأرقام الأربعة الوسطى من رقم هاتف (الصعوبة ⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <regex>
#include <string>

int main() {
	std::string phone = "13812345678";
	std::regex pattern("(\\d{3})\\d{4}(\\d{4})");
	
	std::string result = std::regex_replace(phone, pattern, "$1****$2");
	std::cout << "After hiding:" << result << std::endl;
	
	return 0;
}

نتيجة التشغيل:

TEXT 📖 للعرض فقط
After hiding:138****5678


4. البحث التكراري

(1) 4.1 regex_iterator

مثال: البحث عن جميع عناوين البريد الإلكتروني (الصعوبة ⭐⭐⭐)

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

int main() {
	std::string text = "Contact me:abc@example.com or test@gmail.com";
	std::regex pattern("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
	
	auto begin = std::sregex_iterator(text.begin(), text.end(), pattern);
	auto end = std::sregex_iterator();
	
	std::cout << "Found email: " << std::endl;
	for (auto it = begin; it != end; ++it) {
		std::cout << it->str() << std::endl;
	}
	
	return 0;
}

نتيجة التشغيل:

TEXT 📖 للعرض فقط
Found email: 
abc@example.com
test@gmail.com


5. التجميع والالتقاط

(1) 5.1 التجميع

استخدم الأقواس () لإنشاء مجموعات، والتي يمكنها استخراج سلاسل جزئية.

مثال: استخراج تاريخ (الصعوبة ⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <regex>
#include <string>

int main() {
	std::string date = "2026-06-28";
	std::regex pattern("(\\d{4})-(\\d{2})-(\\d{2})");
	
	std::smatch match;
	if (std::regex_match(date, match, pattern)) {
		std::cout << "Year: " << match[1] << std::endl;
		std::cout << "Month: " << match[2] << std::endl;
		std::cout << "Day: " << match[3] << std::endl;
	}
	
	return 0;
}

نتيجة التشغيل:

TEXT 📖 للعرض فقط
Year: 2026
Month: 06
Day: 28


6. حالات الاستخدام الشائعة

(1) 6.1 التحقق من الإدخال

السيناريو التعبير النمطي
البريد الإلكتروني [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
رقم الهاتف ^1[3-9]\d{9}$
بطاقة الهوية ^\d{17}[\dXx]$
عنوان IP ^(\d{1,3}\.){3}\d{1,3}$

(2) 6.2 استخراج المعلومات

مثال: استخراج روابط من HTML (الصعوبة ⭐⭐⭐)

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

int main() {
	std::string html = "<a href=\"https://example.com\">Example</a>";
	std::regex pattern("<a href=\"([^\"]+)\"");
	
	std::smatch match;
	if (std::regex_search(html, match, pattern)) {
		std::cout << "Link: " << match[1] << std::endl;
	}
	
	return 0;
}

▶ مثال 3: التحقق من صيغة البريد الإلكتروني (الصعوبة ⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <regex>
#include <string>

bool isValidEmail(const std::string& email) {
    std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
    return std::regex_match(email, pattern);
}

int main() {
    std::string emails[] = {"test@example.com", "invalid-email", "user.name@domain.org"};

    for (const auto& email : emails) {
        if (isValidEmail(email)) {
            std::cout << email << " -> Effective" << std::endl;
        } else {
            std::cout << email << " -> Invalid" << std::endl;
        }
    }

    return 0;
}

الخرج:

TEXT 📖 للعرض فقط
 -> Effective
 -> Invalid

❓ أسئلة شائعة

س ماذا لو كانت التعابير النمطية بطيئة جدًا؟
ج - جمّع مرة واحدة، استخدم عدة مرات (مُنشئ std::regex بطيء) - استخدم علامة std::regex_constants::optimize

س: ماذا لو كانت أحرف الهروب كثيرة جدًا؟ ج: استخدم السلاسل الخام (C++11):

CPP
// صعبة القراءة
std::regex pattern("\\\\d+");

// سهلة القراءة
std::regex pattern(R"(\d+)");

س هل يمكن للتعابير النمطية معالجة كل النصوص؟
ج لا. تحليل HTML/XML بالتعابير النمطية معقد جدًا — استخدم محللًا مخصصًا بدلاً من ذلك.

📖 ملخص

النقطة الرئيسية الملخص
regex_match مطابقة كاملة
regex_search بحث
regex_replace استبدال
regex_iterator بحث تكراري
التجميع استخدم () لاستخراج سلاسل جزئية

📝 تمارين

  1. أساسي (الصعوبة ⭐): استخدم std::regex للتحقق مما إذا كانت سلسلة تطابق نمط "أرقام فقط" (^\d+$)، باختبار "123"، "12a3"، "abc".

  2. متوسط (الصعوبة ⭐⭐): استخدم regex_search لاستخراج جميع عناوين البريد الإلكتروني من نص (مطابقة نمط \w+@\w+\.\w+).

  3. متقدم (الصعوبة ⭐⭐⭐): استخدم regex_replace لتنفيذ دالة "فلتر الكلمات الحساسة" — استبدال كلمات حساسة محددة في النص بـ ***. ادعم كلمات حساسة متعددة.



الدرس التالي: أساسيات تعدد الخيوط (#43)

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%