توفّر الحزمة regexp دعمًا للتعبيرات النمطية في Go.
إن صيغة التعبيرات النمطية المقبولة هي نفس الصيغة العامة التي تستخدمها Perl وPython ولغات أخرى.
يُفسَّر كل من أنماط البحث والنصوص المُدخَلة على أنهما بترميز UTF-8.
عند استخدام علامات الاقتباس الخلفية (`) لإنشاء السلاسل النصية، لا يكون للشرطة المائلة العكسية (\) أي معنى خاص ولا تشير إلى بداية محارف خاصة مثل علامات الجدولة \t أو أسطر جديدة \n:
"\t\n" // regular string literal with 2 characters: a tab and a newline
`\t\n`// raw string literal with 4 characters: two backslashes, a 't', and an 'n'
لهذا السبب، من المستحسن استخدام علامات الاقتباس الخلفية لإنشاء التعبيرات النمطية، لأن ذلك يعني أننا لا نحتاج إلى تهريب الشرطات المائلة العكسية:
"\\" // string with a single backslash
`\\` // string with 2 backslashes
RegExp
لاستخدام تعبير نمطي، يجب علينا أولًا تصريف النمط النصي.
التصريف هنا يعني أخذ النمط النصي للتعبير النمطي وتحويله إلى تمثيل داخلي يسهُل التعامل معه.
نحتاج إلى تصريف كل نمط مرة واحدة فقط، وبعد ذلك يمكننا استخدام النسخة المُصرّفة من التعبير النمطي مرات عديدة.
يمثّل النوع regexp.Regexp تعبيرات نمطية مُصرّفة.
يمكننا تصريف نمط نصي إلى regexp.Regexp باستخدام الدالة regexp.Compile.
تُرجع هذه الدالة nil وخطأً إذا فشل التصريف:
re, err := regexp.Compile(`(a|b)+`)
fmt.Println(re, err) // => (a|b)+ <nil>
re, err = regexp.Compile(`a|b)+`)
fmt.Println(re, err) // => <nil> error parsing regexp: unexpected ): `a|b)+`
تُعدّ الدالة MustCompile بديلًا مريحًا عن Compile:
re = regexp.MustCompile(`[a-z]+\d*`)
باستخدام هذه الدالة، لا حاجة إلى معالجة خطأ.
يجب استخدام MustCompile فقط عندما نتأكد تمامًا أن النمط يُصرّف فعلًا، وإلا فسيتعطّل البرنامج.
هناك 16 طريقة في Regexp تُطابق تعبيرًا نمطيًا وتحدّد النص المطابق.
تتطابق أسماؤها مع هذا التعبير النمطي:
Find(All)?(String)?(Submatch)?(Index)?
All موجودًا، تُطابق الدالة المطابقات المتتالية غير المتداخلة للتعبيرات كاملة.String موجودًا، تكون الوسيطة سلسلة نصية؛ وإلا فهي شريحة من البايتات؛ وتُعدَّل القيم المُرجعة وفقًا لذلك.Submatch موجودًا، تكون القيمة المُرجعة شريحة تحدّد المطابقات الفرعية المتتالية للتعبير.Index موجودًا، تُحدَّد المطابقات والمطابقات الفرعية بأزواج فهارس البايتات داخل النص المُدخَل.وهناك أيضًا طرق من أجل:
بشكل عام، تعرّف حزمة regexp أكثر من 40 دالة وطريقة.
سنوضّح استخدام بعض الطرق فيما يلي.
يُرجى الاطلاع على توثيق API لمعرفة تفاصيل هذه الدوال وغيرها.
MatchString
تُخبرنا الطريقة MatchString عمّا إذا كانت سلسلة نصية تحتوي على أي مطابقة لتعبير نمطي.
re = regexp.MustCompile(`[a-z]+\d*`)
b = re.MatchString("[a12]") // => true
b = re.MatchString("12abc34(ef)") // => true
b = re.MatchString(" abc!") // => true
b = re.MatchString("123 456") // => false
FindString
تُرجع الطريقة FindString سلسلة نصية تحتوي على نص المطابقة الأكثر يسارًا للتعبير النمطي.
re = regexp.MustCompile(`[a-z]+\d*`)
s = re.FindString("[a12]") // => "a12"
s = re.FindString("12abc34(ef)") // => "abc34"
s = re.FindString(" abc!") // => "abc"
s = re.FindString("123 456") // => ""
FindStringSubmatch
تُرجع الطريقة FindStringSubmatch شريحة من السلاسل النصية تحتوي على نص المطابقة الأكثر يسارًا للتعبير النمطي وعلى مطابقات تعبيراته الفرعية إن وُجدت.
يمكن استخدام هذا لتحديد السلاسل النصية المطابقة لمجموعات الالتقاط.
تشير القيمة المُرجعة nil إلى عدم وجود مطابقة.
re = regexp.MustCompile(`[a-z]+(\d*)`)
sl = re.FindStringSubmatch("[a12]") // => []string{"a12","12"}
sl = re.FindStringSubmatch("12abc34(ef)") // => []string{"abc34","34"}
sl = re.FindStringSubmatch(" abc!") // => []string{"abc",""}
sl = re.FindStringSubmatch("123 456") // => <nil>
ReplaceAllString
تُرجع الطريقة re.ReplaceAllString(src,repl) نسخة من src، مع استبدال مطابقات التعبير النمطي re بالسلسلة النصية البديلة repl.
re = regexp.MustCompile(`[a-z]+\d*`)
s = re.ReplaceAllString("[a12]", "X") // => "[X]"
s = re.ReplaceAllString("12abc34(ef)", "X") // => "12X(X)"
s = re.ReplaceAllString(" abc!", "X") // => " X!"
s = re.ReplaceAllString("123 456", "X") // => "123 456"
Split
تُجزّئ الطريقة re.Split(s,n) نصًا s إلى سلاسل نصية فرعية مفصولة بالتعبير، وتُرجع شريحة من السلاسل النصية الفرعية الواقعة بين تلك المطابقات.
يحدّد العدد n الحد الأقصى لعدد السلاسل النصية الفرعية المُرجعة.
إذا كان n<0، تُرجع الطريقة كل السلاسل النصية الفرعية.
re = regexp.MustCompile(`[a-z]+\d*`)
sl = re.Split("[a12]", -1) // => []string{"[","]"}
sl = re.Split("12abc34(ef)", 2) // => []string{"12","(ef)"}
sl = re.Split(" abc!", -1) // => []string{" ","!"}
sl = re.Split("123 456", -1) // => []string{"123 456"}
يُضمن أن يعمل تطبيق regexp الذي توفّره هذه الحزمة في زمن خطي بحجم المُدخَل.
تُطبّق الحزمة regexp التعبيرات النمطية RE2 (باستثناء \C).
الصيغة متوافقة إلى حد كبير مع PCRE («تعبير نمطي متوافق مع Perl»)، لكن هناك بعض الاختلافات.
يُرجى الاطلاع على «قسم التحذير» في هذا المقال لمعرفة التفاصيل.