Ramakanta Samal
Ramakanta Samal

Reputation: 241

How to split a string by multiple delimiters

I want to parse a string xxxxx:yyyyy:zzz.aaa.bbb.cc:dd:ee:ff to a struct in Go, how can I do it with multiple delimiter ':' and '.'.

Edit:

I want to split the string "xxxxx:yyyyy:zzz.aaa.bbb.cc:dd" into below struct type

type Target struct {
    Service string
    Type    string
    Domain  string
    Plan    string
    Host    string
    Region  string
    Other   string
}

So that

Service = xxxxx 
Type = yyyyy 
Domain = zzzz 
Plan = aaa 
Host = bbb 
Region = cc 
Other = dd 

Upvotes: 20

Views: 33499

Answers (5)

Nafisa Israil
Nafisa Israil

Reputation: 139

You can use regex for splitting your string

import "regexp"

func splitWord(word string) []string {
    array := regexp.MustCompile("[\\:\\,\\.\\s]+").Split(word, -1)
    return array
}

Upvotes: 12

Dmitry Mottl
Dmitry Mottl

Reputation: 862

You can use this function, which can split a string by multiple runes:

import "fmt"
import "strings"

func SplitAny(s string, seps string) []string {
    splitter := func(r rune) bool {
        return strings.ContainsRune(seps, r)
    }
    return strings.FieldsFunc(s, splitter)
}

func main() {
    words := SplitAny("xxxxx:yyyyy:zzz.aaa.bbb.cc:dd:ee:ff", ".:")
    fmt.Println(strings.Join(words, " "))
}

Output:

xxxxx yyyyy zzz aaa bbb cc dd ee ff

Or even with one line of code:

words := strings.FieldsFunc(s, func(r rune) bool { return strings.ContainsRune(" .:", r) })

Upvotes: 8

Jake Pearson
Jake Pearson

Reputation: 27717

Here is a generic function that will take a string as a set of runes to split on.

func Splitter(s string, splits string) []string {
    m := make(map[rune]int)
    for _, r := range splits {
        m[r] = 1
    }

    splitter := func(r rune) bool {
        return m[r] == 1
    }

    return strings.FieldsFunc(s, splitter)
}

func TestSplit() {
    words := Splitter("orange apple-banana", " -")
}

Upvotes: 2

user6169399
user6169399

Reputation:

You may use

strings.FieldsFunc(input, Split)

Try it on The Go Playground:

package main

import (
    "fmt"
    "strings"
)

func main() {
    input := `xxxxx:yyyyy:zzz.aaa.bbb.cc:dd:ee:ff`
    a := strings.FieldsFunc(input, Split)
    t := Target{a[0], a[1], a[2], a[3], a[4], a[5], a[6]}
    fmt.Println(t) // {xxxxx yyyyy zzz aaa bbb cc dd}
}
func Split(r rune) bool {
    return r == ':' || r == '.'
}

type Target struct {
    Service string
    Type    string
    Domain  string
    Plan    string
    Host    string
    Region  string
    Other   string
}

output:

{xxxxx yyyyy zzz aaa bbb cc dd}

Upvotes: 66

evanmcdonnal
evanmcdonnal

Reputation: 48086

Alright. This isn't a very elegant solution but it should at least get you started and works for the specific example you've given. In reality you'd probably want to add some error handling or generalize the logic a bit to work with a broader set of inputs.

type Target struct {
    Service string
    Type string
    Domain string
    Plan string
    Host string
    Region string
    Other string
}

func main() {
    input := `xxxxx:yyyyy:zzz.aaa.bbb.cc:dd:ee:ff`
    t := Target{}
    tokens := strings.Split(input, ":")
    t.Service = tokens[0]
    t.Type = tokens[1]
    subtokens := strings.Split(tokens[2], ".")
    t.Domain = subtokens[0]
    t.Plan = subtokens[1]
    t.Host = subtokens[2]
    t.Region = subtokens[3]
    t.Other = tokens[3]
    fmt.Printf("%v", t)
}

Working example here; https://play.golang.org/p/57ZyOfdbvo

Upvotes: -1

Related Questions