التعبيرات المنتظمة في Kotlin: دليل كامل مع أمثلة
التعبيرات المنتظمة (regex) هي أداة قوية للبحث عن النص واستخراجه واستبداله وفقًا لنمط معين. في Kotlin، يتم العمل مع التعبيرات المنتظمة من خلال الفئة Regex، التي توفر واجهة برمجة تطبيقات (API) مريحة وتوافقًا كاملاً مع تطبيق Java java.util.regex.Pattern. في هذه المقالة، سنقوم بتحليل جميع جوانب استخدام التعبيرات المنتظمة في Kotlin مع أمثلة توضيحية.
1. إنشاء واستخدام أساسي لـ Regex في Kotlin
يوجد في Kotlin طريقتان رئيسيتان لإنشاء تعبير منتظم:
- مُنشئ الفئة
Regex— تقوم بتمرير سلسلة نصية تحتوي على النمط. - طريقة الامتداد
.toRegex()— يتم استدعاؤها على سلسلة نصية.
أمثلة على الإنشاء:
// الطريقة 1: المُنشئval regex1 = Regex("\\\\d{3}-\\\\d{2}-\\\\d{4}")
// الطريقة 2: toRegex()val regex2 = "\\\\d{3}-\\\\d{2}-\\\\d{4}".toRegex()
// مع العلامات (بحث غير حساس لحالة الأحرف)val regex3 = Regex("hello", RegexOption.IGNORE_CASE)
// وضع متعدد الأسطرval regex4 = Regex("^start", RegexOption.MULTILINE)لاحظ: في Kotlin، كما في Java، يتم استخدام شرطة مائلة مزدوجة \\\\ للهروب من الشرطة المائلة العكسية. إذا كنت تريد كتابة \\d — يجب أن تكتب "\\\\d".
2. الوظائف الأساسية لـ Regex: التحقق، البحث، الاستبدال
توفر الفئة Regex عدة وظائف رئيسية للعمل مع السلاسل النصية.
2.1. التحقق من التطابق الكامل — matches()
تُرجع الدالة matches() القيمة true إذا كانت السلسلة النصية بأكملها تطابق النمط.
val emailRegex = Regex("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}")
val email1 = "user@example.com"val email2 = "invalid-email"
println(emailRegex.matches(email1)) // trueprintln(emailRegex.matches(email2)) // false2.2. البحث عن أول تطابق — find()
تُرجع أول تطابق يتم العثور عليه ككائن من النوع MatchResult? (أو null إذا لم يتم العثور على شيء).
val text = "هاتفي: 123-45-6789 وأيضًا 987-65-4321"val phoneRegex = Regex("\\\\d{3}-\\\\d{2}-\\\\d{4}")
val firstMatch = phoneRegex.find(text)if (firstMatch != null) { println("تم العثور على هاتف: ${firstMatch.value}") // تم العثور على هاتف: 123-45-6789 println("البداية: ${firstMatch.range.first}") // البداية: 7}2.3. البحث عن جميع التطابقات — findAll()
تُرجع تسلسلاً من النوع Sequence<MatchResult> لجميع التطابقات غير المتداخلة.
val text = "الأسعار: 100 روبل، 250 روبل، 50 روبل"val priceRegex = Regex("\\\\d+")
val prices = priceRegex.findAll(text)prices.forEach { match -> println("السعر: ${match.value}")}// الإخراج:// السعر: 100// السعر: 250// السعر: 502.4. الاستبدال وفقًا لنمط — replace()
تستبدل الدالة replace() جميع التطابقات التي تم العثور عليها بسلسلة نصية محددة أو نتيجة تعبير لامدا.
val text = "بريدي الإلكتروني: john@mail.com و support@site.org"val emailRegex = Regex("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}")
// استبدال بسيطval masked = emailRegex.replace(text, "[EMAIL HIDDEN]")println(masked) // بريدي الإلكتروني: [EMAIL HIDDEN] و [EMAIL HIDDEN]
// استبدال مع لامدا (ديناميكي)val replaced = emailRegex.replace(text) { match -> val local = match.value.split("@")[0] "${local.first()}***@***"}println(replaced) // بريدي الإلكتروني: j***@*** و s***@***2.5. تقسيم السلسلة النصية — split()
تقسم السلسلة النصية بناءً على التطابقات مع التعبير المنتظم.
val text = "تفاحة,كمثرى;موز|برتقال"val separators = Regex("[,;|]")
val fruits = separators.split(text)println(fru