التعبيرات النمطية في Go مع أمثلة
التعبيرات النمطية (regex) هي أداة قوية للبحث واستخراج واستبدال النص وفقًا لنمط معين. في لغة Go (Golang)، يتم العمل مع التعبيرات النمطية من خلال الحزمة القياسية regexp. في هذه المقالة، سنشرح بالتفصيل كيفية استخدام التعبيرات النمطية في Go: من البحث البسيط إلى الاستبدالات المعقدة مع مجموعات الالتقاط.
1. أساسيات حزمة regexp
توفر حزمة regexp نهجين رئيسيين: الاستخدام السريع لمرة واحدة (دوال على مستوى الحزمة) والعمل عالي الأداء مع نمط مُجمّع مسبقًا (هيكل Regexp). للاستخدام المتكرر، قم دائمًا بتجميع النمط مسبقًا.
تجميع التعبير النمطي
package main
import ( "fmt" "regexp")
func main() { // تجميع النمط (الطريقة الموصى بها مع معالجة الأخطاء) pattern, err := regexp.Compile(`\\d+`) if err != nil { fmt.Println("خطأ في التجميع:", err) return } // للحالات البسيطة — بدون معالجة أخطاء (تسبب ذعرًا عند نمط غير صالح) patternMust := regexp.MustCompile(`[a-z]+`) fmt.Println(pattern, patternMust)}تقوم Compile بإرجاع خطأ إذا كان النمط غير صالح. MustCompile تسبب ذعرًا — استخدمها فقط مع الأنماط الثابتة.
2. العمليات الأساسية: البحث والتحقق
دعنا نلقي نظرة على الطرق الرئيسية للتحقق من التطابق والبحث عن السلاسل الفرعية.
التحقق من التطابق الجزئي
pattern := regexp.MustCompile(`go`)text := "أنا أدرس Golang"
// MatchString — هل تحتوي السلسلة على سلسلة فرعية تطابق النمطmatched := pattern.MatchString(text)fmt.Println(matched) // true (لأن "go" موجودة في "Golang")التحقق من التطابق الكامل
// للتحقق من أن السلسلة بأكملها تطابق النمط، استخدم المراسي ^ و $fullPattern := regexp.MustCompile(`^[a-zA-Z]+$`)fmt.Println(fullPattern.MatchString("Hello")) // truefmt.Println(fullPattern.MatchString("Hello1")) // falseالبحث عن أول تطابق
datePattern := regexp.MustCompile(`\\d{2}\\.\\d{2}\\.\\d{4}`)text := "اليوم 15.03.2024، وغدًا 16.03.2024"
// FindString — تُرجع أول تطابقfirstDate := datePattern.FindString(text)fmt.Println(firstDate) // "15.03.2024"البحث عن جميع التطابقات
// FindAllString — تُرجع شريحة من جميع التطابقاتallDates := datePattern.FindAllString(text, -1) // -1 — جميع التطابقاتfmt.Println(allDates) // ["15.03.2024" "16.03.2024"]
// تحديد العدد: FindAllString(text, 1) — فقط الأول3. مجموعات الالتقاط والاستبدالات
تسمح مجموعات الالتقاط باستخراج أجزاء من التطابق. في Go، يتم تمييز المجموعات بأقواس دائرية ().
استخراج البيانات حسب المجموعات
// نمط لاستخراج الاسم والعمر: "الاسم: [اسم], العمر: [رقم]"personPattern := regexp.MustCompile(`الاسم: (\\w+), العمر: (\\d+)`)text := "الاسم: أليكسي, العمر: 30"
// FindStringSubmatch — تُرجع شريحة: [التطابق_الكامل, مجموعة1, مجموعة2, ...]matches := personPattern.FindStringSubmatch(text)if len(matches) > 0 { fmt.Println("التطابق الكامل:", matches[0]) // "الاسم: أليكسي, العمر: 30" fmt.Println("الاسم:", matches[1]) // "أليكسي" fmt.Println("العمر:", matches[2]) // "30"}المجموعات المسماة (Go 1.21+)
// منذ الإصدار Go 1.21، يمكن استخدام المجموعات المسماة: (?P<name>pattern)pattern := regexp.MustCompile(`(?P<name>\\w+)@(?P<domain>\\w+\\.\\w+)`)text := "test@example.com"
// SubexpNames — نحصل على أسماء المجموعاتgroupNames := pattern.SubexpNames()matches := pattern.FindStringSubmatch(text)
// ننشئ خريطة: اسم_المجموعة