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: تطبيق التعابير النمطية (الصعوبة ⭐)
#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;
}
الخرج:
Valid phone number
Invalid phone number
نتيجة التشغيل:
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 — البحث
مثال: البحث عن بريد إلكتروني (الصعوبة ⭐⭐)
#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 — الاستبدال
مثال: إخفاء الأرقام الأربعة الوسطى من رقم هاتف (الصعوبة ⭐⭐)
#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;
}
نتيجة التشغيل:
After hiding:138****5678
4. البحث التكراري
(1) 4.1 regex_iterator
مثال: البحث عن جميع عناوين البريد الإلكتروني (الصعوبة ⭐⭐⭐)
#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;
}
نتيجة التشغيل:
Found email:
abc@example.com
test@gmail.com
5. التجميع والالتقاط
(1) 5.1 التجميع
استخدم الأقواس () لإنشاء مجموعات، والتي يمكنها استخراج سلاسل جزئية.
مثال: استخراج تاريخ (الصعوبة ⭐⭐)
#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;
}
نتيجة التشغيل:
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 (الصعوبة ⭐⭐⭐)
#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: التحقق من صيغة البريد الإلكتروني (الصعوبة ⭐)
#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;
}
الخرج:
-> Effective
-> Invalid
❓ أسئلة شائعة
std::regex بطيء) - استخدم علامة std::regex_constants::optimizeس: ماذا لو كانت أحرف الهروب كثيرة جدًا؟ ج: استخدم السلاسل الخام (C++11):
// صعبة القراءة
std::regex pattern("\\\\d+");
// سهلة القراءة
std::regex pattern(R"(\d+)");
📖 ملخص
| النقطة الرئيسية | الملخص |
|---|---|
| regex_match | مطابقة كاملة |
| regex_search | بحث |
| regex_replace | استبدال |
| regex_iterator | بحث تكراري |
| التجميع | استخدم () لاستخراج سلاسل جزئية |
📝 تمارين
-
أساسي (الصعوبة ⭐): استخدم
std::regexللتحقق مما إذا كانت سلسلة تطابق نمط "أرقام فقط" (^\d+$)، باختبار "123"، "12a3"، "abc". -
متوسط (الصعوبة ⭐⭐): استخدم
regex_searchلاستخراج جميع عناوين البريد الإلكتروني من نص (مطابقة نمط\w+@\w+\.\w+). -
متقدم (الصعوبة ⭐⭐⭐): استخدم
regex_replaceلتنفيذ دالة "فلتر الكلمات الحساسة" — استبدال كلمات حساسة محددة في النص بـ***. ادعم كلمات حساسة متعددة.
- التعابير النمطية: مطابقة أنماط السلاسل
- std::regex يُنشئ كائنات تعابير نمطية
- std::regex_match للمطابقة الكاملة
- std::regex_search لمطابقة البحث
- std::regex_replace يستبدل المحتوى المطابق
الدرس التالي: أساسيات تعدد الخيوط (#43)