5

I am trying to split a string by the last occurrence of a separator (/) in golang

Example, I have a string "a/b/c/d", after performing the split, I would like an array of string as below

[
"a/b/c",
"a/b"
"a"
]

I tried exploring strings package but couldn't find any function that does this

func main() {
    fmt.Printf("%q\n", strings.Split("a/b/c/d/e", "/"))
}

May I know a way to handle this?

DoIt
  • 3,270
  • 9
  • 51
  • 103
  • 4
    There's [`strings.LastIndex`](https://golang.org/pkg/strings/#LastIndex). Is this only for path operations? If so there's also [`path.Split`](https://golang.org/pkg/path/#Split). – JimB Jul 30 '18 at 16:28
  • Yes, this is only for path operations – DoIt Jul 30 '18 at 16:29

3 Answers3

13

To split any string only at the last occurrence, using strings.LastIndex

import (
    "fmt"
    "strings"
)

func main() {
    x := "a_ab_daqe_sd_ew"
    lastInd := strings.LastIndex(x, "_")
    fmt.Println(x[:lastInd]) // o/p: a_ab_daqe_sd
    fmt.Println(x[lastInd+1:]) // o/p: ew
}

Note, strings.LastIndex returns -1 if substring passed(in above example, "_") is not found

Riya John
  • 474
  • 4
  • 14
4

Since this is for path operations, and it looks like you don't want the trailing path separator, then path.Dir does what you're looking for:

fmt.Println(path.Dir("a/b/c/d/e"))
// a/b/c/d

If this is specifically for filesystem paths, you will want to use the filepath package instead, to properly handle multiple path separators.

JimB
  • 104,193
  • 13
  • 262
  • 255
1

Here's a simple function that uses filepath.Dir(string) to build a list of all ancestor directories of a given filepath:

func main() {
  fmt.Printf("OK: %#v\n", parentsOf("a/b/c/d"))
  // OK: []string{"a/b/c", "a/b", "a"}
}

func parentsOf(s string) []string {
  dirs := []string{}
  for {
    parent := filepath.Dir(s)
    if parent == "." || parent == "/" {
      break
    }
    dirs = append(dirs, parent)
    s = parent
  }
  return dirs
}
maerics
  • 151,642
  • 46
  • 269
  • 291