2014-09-05 11 views
7

Kann jemand eine Zeichenfolge in Golang nach Länge aufteilen?Split String von Länge in Golang

Zum Beispiel, um "helloworld" nach jeweils 3 Zeichen zu teilen, so sollte es idealerweise ein Array von "hel" "low" "orl" "d" zurückgeben?

Alternativ kann eine mögliche Lösung wäre, auch eine neue Zeile nach jeweils 3 Zeichen anhängen ..

Alle Ideen sehr geschätzt werden!

+3

Nun, einige Programmierung könnte hier helfen? Wie 's [n: n + 3] +" \ n "'? – Volker

Antwort

17

Stellen Sie sicher, convert Ihre string in eine Scheibe von Rune: siehe "Slice string into letters"

a := []rune(s) 
for i, r := range a { 
    fmt.Printf("i%d r %c\n", i, r) 
    // every 3 i, do something 
} 

a[n:n+3] am besten funktionieren wird mit einem ein Stück Rune zu sein.

wird der Index von eine jede Rune erhöhen, während es in einem slice of string für jedes Byte von mehr als ein Anstieg könnte: „世界“: sein kann, ein Zeichen (Rune): i 0 und 3 wäre aus mehreren Bytes gebildet.


Betrachten wir zum Beispiel s := "世a界世bcd界efg世": 12 Runen. (Siehe play.golang.org)

Wenn Sie versuchen, es für Byte Byte zu analysieren, werden Sie (in einer naiven geteilte Implementierung alle 3 Zeichen) verpassen einige der "Index modulo 3" (entspricht 2, 5, 8 und 11), weil der Index Vergangenheit diese Werte erhöhen:

for i, r := range s { 
    res = res + string(r) 
    fmt.Printf("i %d r %c\n", i, r) 
    if i > 0 && (i+1)%3 == 0 { 
     fmt.Printf("=>(%d) '%v'\n", i, res) 
     res = "" 
    } 
} 

der Ausgang:

i 0 r 世 
i 3 r a <== miss i==2 
i 4 r 界 
i 7 r 世 <== miss i==5 
i 10 r b <== miss i==8 
i 11 r c ===============> would print '世a界世bc', not exactly '3 chars'! 
i 12 r d 
i 13 r 界 
i 16 r e <== miss i==14 
i 17 r f ===============> would print 'd界ef' 
i 18 r g 
i 19 r 世 <== miss the rest of the string 

Aber wenn man auf Runen (a := []rune(s)) iterieren, würden Sie bekommen, was Sie erwarten, wie die Index würde inc Rease eine Rune zu einer Zeit, ist es leicht zu aggregieren genau 3 Zeichen machen:

for i, r := range a { 
    res = res + string(r) 
    fmt.Printf("i%d r %c\n", i, r) 
    if i > 0 && (i+1)%3 == 0 { 
     fmt.Printf("=>(%d) '%v'\n", i, res) 
     res = "" 
    } 
} 

Ausgang:

i 0 r 世 
i 1 r a 
i 2 r 界 ===============> would print '世a界' 
i 3 r 世 
i 4 r b 
i 5 r c ===============> would print '世bc' 
i 6 r d 
i 7 r 界 
i 8 r e ===============> would print 'd界e' 
i 9 r f 
i10 r g 
i11 r 世 ===============> would print 'fg世' 
2

auch eine Funktion benötigt, um dies vor kurzem zu tun, example usage here

func SplitSubN(s string, n int) []string { 
    sub := "" 
    subs := []string{} 

    runes := bytes.Runes([]byte(s)) 
    l := len(runes) 
    for i, r := range runes { 
     sub = sub + string(r) 
     if (i + 1) % n == 0 { 
      subs = append(subs, sub) 
      sub = "" 
     } else if (i + 1) == l { 
      subs = append(subs, sub) 
     } 
    } 

    return subs 
} 
1

sehen Hier ist ein weiteres Beispiel (Sie können es versuchen here):

package main 

import (
    "fmt" 
    "strings" 
) 

func ChunkString(s string, chunkSize int) []string { 
    var chunks []string 
    runes := []rune(s) 

    if len(runes) == 0 { 
     return []string{s} 
    } 

    for i := 0; i < len(runes); i += chunkSize { 
     nn := i + chunkSize 
     if nn > len(runes) { 
      nn = len(runes) 
     } 
     chunks = append(chunks, string(runes[i:nn])) 
    } 
    return chunks 
} 

func main() { 
    fmt.Println(ChunkString("helloworld", 3)) 
    fmt.Println(strings.Join(ChunkString("helloworld", 3), "\n")) 
} 
-1

Eine einfache Lösung regex

re verwendet: = regexp.MustCompile ((\S{3})) x: = re.FindAllStringSubmatch ("Hello World", -1) fmt.Println (x)

https://play.golang.org/p/mfmaQlSRkHe

+0

ich bekomme es nicht –

+0

Didi du es in The Go Playground laufen?Könnten Sie bitte mich wissen lassen, was Sie nicht verstanden haben? – rahul