Skip to content

strings

حزمة strings تنفذ دوال بسيطة للتعامل مع السلاسل المشفرة بـ UTF-8، وببساطة هي حزمة أدوات للتعامل مع السلاسل.

الوثائق الرسمية: strings package - strings - Go Packages

TIP

تدعم Go بشكل أصلي UTF8، وجميع عمليات السلاسل مبنية على أساس UTF8.

الاستيراد

go
import (
   "strings"
)

فيما يلي سيتم شرح الدوال الشائعة من خلال أمثلة.

نسخ سلسلة

go
func Clone(s string) string

ستُخصص ذاكرة جديدة للنسخة المنسوخة، إذا تم تمرير سلسلة فارغة، فلن تُخصص ذاكرة وسيُرجع سلسلة فارغة.

go
func TestClone(t *testing.T) {
   ori := "hello 世界"
   copys := strings.Clone(ori)
   fmt.Println(ori, copys)
   fmt.Println(&ori, &copys)
}
=== RUN   TestClone
hello 世界 hello 世界
0xc00005e5d0 0xc00005e5e0
--- PASS: TestClone (0.00s)
PASS

مقارنة السلاسل

go
func Compare(a, b string) int

تتم مقارنة a و b حسب الترتيب المعجمي، إذا a>b تُرجع 1، وإذا a<b تُرجع -1، وإذا a=b تُرجع 0.

go
func TestCompare(t *testing.T) {
  fmt.Println(strings.Compare("abc", "abe"))
  fmt.Println(strings.Compare("abcd", "abe"))
  fmt.Println(strings.Compare("abijk", "abe"))
  fmt.Println(strings.Compare("abe", "abe"))
}
=== RUN   TestCompare
-1
-1
1
0
--- PASS: TestCompare (0.00s)
PASS

احتواء سلسلة

go
func Contains(s, substr string) bool

للتحقق مما إذا كانت السلسلة s تحتوي على سلسلة فرعية substr

go
func TestContains(t *testing.T) {
  fmt.Println(strings.Contains("abcdefg", "a"))
  fmt.Println(strings.Contains("abcdefg", "abc"))
  fmt.Println(strings.Contains("abcdefg", "ba"))
}
=== RUN   TestContains
true
true
false
--- PASS: TestContains (0.00s)
PASS
go
func ContainsAny(s, chars string) bool

للتحقق مما إذا كان أي حرف من أحرف السلسلة chars موجود في السلسلة s

go
func TestContainsAny(t *testing.T) {
  fmt.Println(strings.ContainsAny("abcedfg", "bac"))
  fmt.Println(strings.ContainsAny("abcedfg", "gfdecba"))
}
=== RUN   TestContainsAny
true
--- PASS: TestContainsAny (0.00s)
PASS
go
func ContainsRune(s string, r rune) bool

للتحقق مما إذا كانت السلسلة s تحتوي على الحرف r

go
func TestContainsRune(t *testing.T) {
   fmt.Println(strings.ContainsRune("abcedf", 'a'))
   fmt.Println(strings.ContainsRune("abcedf", 'b'))
   fmt.Println(strings.ContainsRune("你好世界", ''))
}
=== RUN   TestContainsRune
true
true
true
--- PASS: TestContainsRune (0.00s)
PASS

عدد مرات ظهور السلسلة الفرعية

go
func Count(s, substr string) int

تُرجع عدد مرات ظهور السلسلة الفرعية substr في السلسلة s

go
func TestCount(t *testing.T) {
  fmt.Println(strings.Count("3.1415926", "1"))
  fmt.Println(strings.Count("there is a girl", "e"))
  fmt.Println(strings.Count("there is a girl", ""))
}
=== RUN   TestCount
2
2
16
--- PASS: TestCount (0.00s)
PASS

حذف سلسلة فرعية محددة

go
func Cut(s, sep string) (before, after string, found bool)

تحذف أول ظهور للسلسلة الفرعية sep في s، وتُرجع النتيجة بعد الحذف

  • before - السلسلة قبل موضع السلسلة الفرعية المحذوفة
  • after - السلسلة بعد موضع السلسلة الفرعية المحذوفة
  • found - هل تم العثور على السلسلة الفرعية
go
func TestCut(t *testing.T) {
  show := func(s, sep string) {
    before, after, found := strings.Cut(s, sep)
    fmt.Printf("Cut(%q, %q) = %q, %q, %v\n", s, sep, before, after, found)
  }
  show("Hello world", " ")
  show("Hello world", "world")
  show("Hello world", "Hello")
  show("Hello world", "Hello world")
}
=== RUN   TestCut
Cut("Hello world", " ") = "Hello", "world", true
Cut("Hello world", "world") = "Hello ", "", true
Cut("Hello world", "Hello") = "", " world", true
Cut("Hello world", "Hello world") = "", "", true
--- PASS: TestCut (0.00s)
PASS

المساواة مع تجاهل حالة الأحرف

go
func EqualFold(s, t string) bool

تُرجع ما إذا كانت السلسلتان s و t متساويتين عند تجاهل حالة الأحرف

go
func TestEqualFold(t *testing.T) {
   fmt.Println(strings.EqualFold("你好", "你好"))
   fmt.Println(strings.EqualFold("Hello", "Hello"))
   fmt.Println(strings.EqualFold("Hello", "hELLO"))
}
=== RUN   TestEqualFold
true
true
true
--- PASS: TestEqualFold (0.00s)
PASS

تقسيم السلسلة

go
func Fields(s string) []string
go
func FieldsFunc(s string, f func(rune) bool) []string

الأولى تقسم السلسلة حسب المسافات، والثانية تقسم حسب القيمة المرجعة للدالة f.

go
func TestField(t *testing.T) {
   fmt.Printf("%q\n", strings.Fields(" a b c d e f g "))
   fmt.Printf("%q\n", strings.FieldsFunc("a,b,c,d,e,f,g", func(r rune) bool {
      return r == ','
   }))
}
=== RUN   TestField
["a" "b" "c" "d" "e" "f" "g"]
["a" "b" "c" "d" "e" "f" "g"]
--- PASS: TestField (0.00s)
PASS

البحث عن البادئة واللاحقة

go
func HasPrefix(s, prefix string) bool
go
func HasSuffix(s, suffix string) bool

الأولى للبحث عن البادئة، والثانية للبحث عن اللاحقة، إذا كنت مهتماً يمكنك الاطلاع على الكود المصدري هنا، فهو ذكي جداً.

go
func TestPreSuffix(t *testing.T) {
   str := "abbc cbba"
   fmt.Println(strings.HasPrefix(str, "abb"))
   fmt.Println(strings.HasSuffix(str, "bba"))
}
=== RUN   TestPreSuffix
true
true
--- PASS: TestPreSuffix (0.00s)
PASS

موضع السلسلة الفرعية

تُرجع فهرس أول ظهور للسلسلة الفرعية

go
func Index(s, substr string) int

تُرجع فهرس أول ظهور لأي حرف من السلسلة الفرعية

go
func IndexAny(s, chars string) int

تُرجع فهرس أول ظهور للحرف

go
func IndexRune(s string, r rune) int

مثال

go
func TestIndex(t *testing.T) {
   fmt.Println(strings.Index("abcdefg", "bc"))
   fmt.Println(strings.IndexAny("abcdefg", "cb"))
   fmt.Println(strings.IndexRune("abcdefg", 'g'))
}
=== RUN   TestIndex
1
1
6
--- PASS: TestIndex (0.00s)
PASS

تُرجع فهرس آخر ظهور للسلسلة الفرعية

go
func LastIndex(s, substr string) int

تُرجع فهرس آخر ظهور لأي حرف من السلسلة الفرعية

go
func LastIndexAny(s, chars string) int

مثال

go
func TestLastIndex(t *testing.T) {
  fmt.Println(strings.LastIndex("abcdefga", "a"))
  fmt.Println(strings.LastIndexAny("abcdefghisa", "ba"))
}

تكرار استبدال السلسلة

تُرجع Map نسخة من السلسلة s، وتُعدّل جميع أحرف السلسلة s حسب دالة التخطيط. إذا أعادت دالة التخطيط قيمة سالبة، يُحذف الحرف من السلسلة دون استبداله

go
func Map(mapping func(rune) rune, s string) string

مثال

go
func TestMap(t *testing.T) {
   fmt.Println(strings.Map(func(r rune) rune {
      return r - 32
   }, "abcdefghijk"))
   fmt.Println(strings.Map(func(r rune) rune {
      return r + 32
   }, "ABCDEFGHIJK"))
   fmt.Println(strings.Map(func(r rune) rune {
      if r < 'F' {
         return -1
      } else {
         return r
      }
   }, "ABCDEFGHIJK"))
}

الإخراج

text
=== RUN   TestMap
ABCDEFGHIJK
abcdefghijk
FGHIJK
--- PASS: TestMap (0.00s)
PASS

تكرار نسخ السلسلة

نسخ السلسلة حسب العدد المحدد، إذا كان سالباً سيسبب panic

go
func Repeat(s string, count int) string

مثال

go
func TestRepeat(t *testing.T) {
   fmt.Println(strings.Repeat("a", 10))
   fmt.Println(strings.Repeat("abc", 10))
}

الإخراج

=== RUN   TestRepeat
aaaaaaaaaa
abcabcabcabcabcabcabcabcabcabc
--- PASS: TestRepeat (0.00s)
PASS

استبدال السلسلة

s هي السلسلة الأصلية، وold هو الجزء المراد استبداله، وnew هو جزء الاستبدال لـ old، وn هو عدد مرات الاستبدال، عندما n أقل من 0 يعني عدم تقييد عدد مرات الاستبدال.

go
func Replace(s, old, new string, n int) string

مثال

go
func TestReplace(t *testing.T) {
   fmt.Println(strings.Replace("Hello this is golang", "golang", "c++", 1))
   fmt.Println(strings.Replace("Hello this is golang", "o", "c", -1))
   fmt.Println(strings.Replace("Hello this is golang", "o", "c", 1))
}

الإخراج

=== RUN   TestReplace
Hello this is c++
Hellc this is gclang
Hellc this is golang
--- PASS: TestReplace (0.00s)
PASS

دالة ملائمة لـ Replace، تكافئ stings.Replace(s,old,new,-1)

go
func ReplaceAll(s, old, new string) string

مثال

go
func TestReplaceAll(t *testing.T) {
  fmt.Println(strings.ReplaceAll("Hello this is golang", "o", "c++"))
}

الإخراج

=== RUN   TestReplaceAll
Hellc++ this is gc++lang
--- PASS: TestReplaceAll (0.00s)
PASS

فصل السلسلة

فصل السلسلة s إلى شريحة سلاسل حسب السلسلة الفرعية sep

go
func Split(s, sep string) []string

فصل السلسلة s إلى شريحة سلاسل حسب السلسلة الفرعية sep، وعدد مرات الفصل يحدده n

go
func SplitN(s, sep string, n int) []string

فصل السلسلة s إلى شريحة سلاسل تتضمن عناصر تحتوي على sep

go
func SplitAfter(s, sep string) []string

فصل السلسلة s إلى شريحة سلاسل تتضمن عناصر تحتوي على sep، وعدد مرات الفصل يحدده n

go
func SplitAfterN(s, sep string, n int) []string

مثال

go
func TestSplit(t *testing.T) {
   fmt.Printf("%q\n", strings.Split("this is go language", " "))
   fmt.Printf("%q\n", strings.SplitN("this is go language", " ", 2))
   fmt.Printf("%q\n", strings.SplitAfter("this is go language", " "))
   fmt.Printf("%q\n", strings.SplitAfterN("this is go language", " ", 2))
}

الإخراج

=== RUN   TestSplit
["this" "is" "go" "language"]
["this" "is go language"]
["this " "is " "go " "language"]
["this " "is go language"]
--- PASS: TestSplit (0.00s)
PASS

تحويل حالة الأحرف

تحويل السلسلة الإنجليزية إلى أحرف صغيرة

go
func ToLower(s string) string

التحويل إلى أحرف صغيرة حسب اللغة المحددة عبر unicode.SpecialCase

go
func ToLowerSpecial(c unicode.SpecialCase, s string) string

تحويل السلسلة الإنجليزية إلى أحرف كبيرة

go
func ToUpper(s string) string

التحويل إلى أحرف كبيرة حسب اللغة المحددة عبر unicode.SpecialCase

go
func ToUpperSpecial(c unicode.SpecialCase, s string) string

مثال

go
func TestLowerAndUpper(t *testing.T) {
   fmt.Println(strings.ToLower("My name is jack,Nice to meet you!"))
   fmt.Println(strings.ToLowerSpecial(unicode.TurkishCase, "Önnek İş"))
   fmt.Println(strings.ToUpper("My name is jack,Nice to meet you!"))
   fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, "örnek iş"))
}

الإخراج

=== RUN   TestLowerAndUpper
my name is jack,nice to meet you!
önnek iş
MY NAME IS JACK,NICE TO MEET YOU!
ÖRNEK İŞ
--- PASS: TestLowerAndUpper (0.00s)
PASS

تقليم السلسلة

تقليم طرفي السلسلة، وحذف أي سلسلة فرعية تطابق cutset

go
func Trim(s, cutset string) string

تقليم الطرف الأيسر للسلسلة، وحذف أي سلسلة فرعية تطابق cutset

go
func TrimLeft(s, cutset string) string

تقليم بادئة الطرف الأيسر للسلسلة، وحذف السلسلة الفرعية التي تطابق cutset، إذا لم تتطابق تُرجع السلسلة s

go
func TrimPrefix(s, suffix string) string

تقليم الطرف الأيمن للسلسلة، وحذف أي سلسلة فرعية تطابق cutset

go
func TrimRight(s, cutset string) string

تقليم لاحقة الطرف الأيمن للسلسلة، وحذف السلسلة الفرعية التي تطابق cutset، إذا لم تتطابق تُرجع السلسلة s

go
func TrimSuffix(s, suffix string) string

مثال

go
func TestTrim(t *testing.T) {
  fmt.Println(strings.Trim("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimLeft("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimRight("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimPrefix("!!this is a test statement!!", "!!!"))
  fmt.Println(strings.TrimSuffix("!!this is a test statement!!", "!!!"))
}

الإخراج

=== RUN   TestTrim
this is a test statement
this is a test statement!!
!!this is a test statement
!!this is a test statement!!
!!this is a test statement!!
--- PASS: TestTrim (0.00s)
PASS

منشئ السلاسل Builder

منشئ السلاسل Builder أكثر توفيراً للذاكرة من التعامل المباشر مع السلاسل.

go
type Builder struct {
  // حقول داخلية غير مكشوفة للخارج
}

مثال

go
func TestBuilder(t *testing.T) {
   builder := strings.Builder{}
   builder.WriteString("hello")
   builder.WriteString(" world")
   fmt.Println(builder.Len())
   fmt.Println(builder.String())
}

الإخراج

=== RUN   TestBuilder
11
hello world
--- PASS: TestBuilder (0.00s)
PASS

TIP

لا تحاول تمرير Builder كقيمة، مثلاً عند تمرير strings.Builder كمعامل دالة، سيُسبب البرنامج panic

strings: illegal use of non-zero Builder copied by value

يوجد داخلياً الكود التالي

go
type Builder struct {
  addr *Builder // عنوانه الخاص
  buf  []byte
}

func (b *Builder) copyCheck() {
   if b.addr == nil {
      b.addr = (*Builder)(noescape(unsafe.Pointer(b)))
   } else if b.addr != b {
      panic("strings: illegal use of non-zero Builder copied by value")
   }
}

عند نسخ Builder كقيمة، يتم أيضاً نسخ مؤشر الشريحة الداخلية، وكلا Builder عند كتابة السلاسل يتعاملان مع نفس الشريحة، وهذا هو السبب في عدم السماح بالنسخ كقيمة.

مستبدل السلاسل Replacer

Replacer مخصص لاستبدال السلاسل

go
func NewReplacer(oldnew ...string) *Replacer

مثال

go
func TestReplacer(t *testing.T) {
  r := strings.NewReplacer("<", "<", ">", ">")
  fmt.Println(r.Replace("This is <b>HTML</b>!"))
}

الإخراج

This is <b>HTML</b>!

قارئ السلاسل Reader

ينفذ Reader الواجهات io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker, و io.WriterTo interfaces.

go
func NewReader(s string) *Reader

مثال

go
func TestReader(t *testing.T) {
   reader := strings.NewReader("abcdefghijk")
   buffer := make([]byte, 20, 20)
   read, err := reader.Read(buffer)
   if err != nil {
      log.Panic(err)
   }
   fmt.Println(read)
   fmt.Println(string(buffer))
}

الإخراج

=== RUN   TestReader
11
abcdefghijk
--- PASS: TestReader (0.00s)
PASS

Golang تم تحريره بواسطة www.golangdev.cn