Menu
flag Ar iconالعربيةdown icon

النصوص في Golang: Split وJoin وContains وReplace وغيرها

العمل مع النصوص في Go: الحزمة strings (Split وJoin وContains وReplace وFields وTrimSpace وToUpper)، وبناء النصوص بكفاءة بـ strings.Builder، والنصوص الخام متعدّدة الأسطر، وعدم قابلية التعديل، ولماذا تعدّ len البايتات.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

النص في Go سلسلة غير قابلة للتعديل من البايتات، وعادة ما يكون نصًا بترميز UTF-8. تعمل المعاملات على النص نفسه (+ و== و< والفهرسة والتقطيع)، وكل ما عدا ذلك يعيش في الحزمة القياسية strings.

تقسيم النصوص

الدالةتقسم عندملاحظات
Split(s, sep)كل sepتحتفظ بالأجزاء الفارغة؛ تعيد Split("", ",") القيمة [""]، نصًا فارغًا واحدًا
SplitN(s, sep, n)n جزءًا على الأكثريحمل الجزء الأخير البقية
SplitAfter(s, sep)كل sepتُبقي الفاصل في كل جزء
Fields(s)تتابعات المسافات البيضاءلا تعيد أجزاء فارغة أبدًا
FieldsFunc(s, f)الأحرف التي تكون f صحيحة لهافواصل مخصّصة
Cut(s, sep)أول sep فقطتعيد ما قبله وما بعده وهل وُجد (Go 1.18)

حالة Split("", ",") تفاجئ الناس: المدخل الفارغ يعطي شريحة طولها 1، لا 0. عند تقسيم مدخلات المستخدم، تتجنّب Fields أو فحص s == "" أولًا عنصرًا فارغًا وهميًا.

strings.Cut أنظف طريقة لتقسيم key=value وuser@host والأزواج المشابهة. وأضافت Go 1.24 أيضًا نسخًا بمكرِّرات، strings.SplitSeq وstrings.FieldsSeq، تعطي الأجزاء واحدًا تلو الآخر دون بناء شريحة.

البحث

الدالةتعيد
Contains(s, sub)true إذا ظهر sub في s
ContainsAny(s, chars)true إذا ظهر أي حرف من chars
HasPrefix(s, p) / HasSuffix(s, p)true إذا بدأ s أو انتهى بـ p
Index(s, sub)موضع البايت لأول مطابقة، أو -1
LastIndex(s, sub)موضع البايت لآخر مطابقة، أو -1
Count(s, sub)عدد المطابقات غير المتداخلة
EqualFold(a, b)المساواة دون تمييز حالة الأحرف

كل بحث يميّز حالة الأحرف ما عدا EqualFold. للبحث دون تمييز حالة الأحرف، حوّل الطرفين إلى حروف صغيرة أو استخدم EqualFold لمقارنة النصوص كاملة.

التحويل

فخ واحد: تأخذ Trim وTrimLeft وTrimRight مجموعة أحرف، لا بادئة. تزيل strings.TrimLeft("abcab", "ab") كل a وb في البداية وتعيد "cab". لإزالة بادئة أو لاحقة بعينها استخدم TrimPrefix وTrimSuffix.

الضمّ وstrings.Builder

يضمّ + النصوص، وتنسّق fmt.Sprintf القيم في نص واحد. كلاهما يحجز نصًا جديدًا في كل مرة، لأن النصوص غير قابلة للتعديل. هذا مقبول لعدد قليل من العمليات وبطيء في حلقة، حيث ينسخ كل += كل ما بُني حتى الآن. استخدم strings.Builder بدلًا من ذلك:

الـ strings.Builder الصفري جاهز للاستخدام. يطبّق io.Writer، فتكتب فيه fmt.Fprintf مباشرة. استدعِ b.Grow(n) أولًا إذا كنت تعرف تقريبًا حجم النتيجة. لا تنسخ Builder بعد الكتابة فيه؛ مرّر مؤشرًا.

النصوص متعدّدة الأسطر والخام

لدى Go نوعان من حرفيات النصوص:

تعالج النصوص بين علامتي الاقتباس المزدوجتين رموز الهروب (\n و\t و\" و\\ و\u00e9) ويجب أن تتّسع في سطر واحد. أما النصوص الخام بين علامتي الاقتباس المائلتين فتأخذ كل شيء حرفيًا، بما في ذلك الأسطر الجديدة، وهذا يجعلها طريقة كتابة النصوص متعدّدة الأسطر والتعابير النمطية وJSON ومسارات Windows. لا يمكن للنص الخام أن يحتوي علامة الاقتباس المائلة، وتُحذف منه محارف العودة (carriage return). لاحظ أن الاستعلام السابق يبدأ بسطر جديد، لأن الحرفية تبدأ مباشرة بعد علامة الاقتباس المائلة الافتتاحية.

الطول والفهرسة والنصوص الفرعية

len(s) هو عدد البايتات. وs[i] بايت، وs[i:j] نص فرعي بمواضع البايتات:

يشغل كل من ï وé بايتين، فالنص 12 بايتًا و10 أحرف. التقطيع بالبايتات آمن ما دامت المواضع تأتي من strings.Index أو ما يشبهها، التي تعيد إزاحات بايتات على حدود الأحرف. لأخذ "أول n حرفًا" حوّل إلى []rune أولًا. صفحة الـ runes والبايتات تشرح UTF-8 بالتفصيل.

النصوص غير قابلة للتعديل

لا يمكنك تغيير بايت في مكانه: s[0] = 'H' خطأ ترجمة (cannot assign to s[0] (neither addressable nor a map index expression)). كل دالة في strings تعيد نصًا جديدًا. للتعديل حوّل إلى []byte أو []rune، وغيّر الشريحة، ثم حوّل بالعكس:

b := []byte("hello")
b[0] = 'H'
s := string(b) // "Hello"

عدم قابلية التعديل هو أيضًا سبب رخص النصوص الفرعية: تتشارك s[2:5] الذاكرة مع s بدل نسخها. والوجه الآخر أن نصًا فرعيًا صغيرًا من نص ضخم يُبقي النص الضخم كله حيًّا. استخدم strings.Clone (Go 1.20) عندما تحتفظ بقطعة قصيرة من مدخل كبير.

مقارنة النصوص

تقارن == و!= المحتوى، وتقارن < و> بايتًا ببايت، وهذا ترتيب أبجدي في ASCII. توجد strings.Compare لكن نادرًا ما تُحتاج؛ وslices.Sort على []string تستخدم <. للترتيب المراعي للغة المحلية في النصوص غير الإنجليزية استخدم golang.org/x/text/collate.

تحويل الأنواع الأخرى

تصير الأرقام نصوصًا بـ strconv.Itoa أو strconv.FormatFloat أو fmt.Sprintf، وتصير النصوص أرقامًا بـ strconv.Atoi وstrconv.ParseFloat. لا تكتب string(42): فهي تنتج الحرف صاحب نقطة الرمز 42، أي "*". صفحة تحويل الأنواع فيها الجدول الكامل.

الأسئلة الشائعة

كيف أقسّم نصًا في Go؟

استخدم strings.Split(s, sep): تعيد strings.Split("a,b,c", ",") القيمة ["a" "b" "c"]. للتقسيم على أي تتابع من المسافات البيضاء وإسقاط الأجزاء الفارغة استخدم strings.Fields(s). تحدّ strings.SplitN عدد الأجزاء، وتقسم strings.Cut مرة واحدة حول أول فاصل.

كيف أكتب نصًا متعدّد الأسطر في Go؟

استخدم حرفية نص خام بين علامتي الاقتباس المائلتين:

query := `SELECT id, name
FROM users
WHERE active = true`

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

كيف أتحقّق من احتواء نص على نص فرعي في Go؟

تعيد strings.Contains(s, substr) قيمة bool. دوال مرتبطة: strings.HasPrefix وstrings.HasSuffix وstrings.Index (الموضع أو -1) وstrings.ContainsAny (أي حرف من مجموعة أحرف) وstrings.EqualFold للمساواة دون تمييز حالة الأحرف.

ما أسرع طريقة لضمّ النصوص في Go؟

لبضعة نصوص يكفي +. أما عند بناء نص في حلقة فاستخدم strings.Builder: استدعِ WriteString مرارًا وString() مرة واحدة في النهاية. تكرار += في حلقة ينسخ النص كله في كل مرة، فيبطؤ مع نمو النص. ولضمّ شريحة بفاصل استخدم strings.Join.

لماذا تعيد len طولًا خاطئًا لنصي؟

تعيد len(s) عدد البايتات لا الأحرف. نصوص Go بترميز UTF-8، حيث تشغل الأحرف خارج ASCII من 2 إلى 4 بايتات، فتكون len("héllo") مساوية لـ 6. استخدم utf8.RuneCountInString(s) لعدد نقاط رمز Unicode.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن