Use standard slice syntax str[start:end] to extract substrings, where start is inclusive and end is exclusive. For UTF-8 safety with multi-byte characters, convert the string to a []rune slice first to avoid cutting characters in half.
Here is the standard approach for ASCII or known-safe strings:
package main
import "fmt"
func main() {
s := "Hello, World!"
// Extract "World" (index 7 to 11)
sub := s[7:12]
fmt.Println(sub) // Output: World
// Extract from index 7 to the end
sub2 := s[7:]
fmt.Println(sub2) // Output: World!
}
If you are dealing with Unicode text (like emojis or non-ASCII characters), slicing by byte index will corrupt the string. Always convert to runes:
package main
import "fmt"
func main() {
s := "Hello 🚀 World"
// Incorrect: s[6:7] might cut the emoji in half
// Correct: Convert to runes first
r := []rune(s)
// Extract the emoji (index 6 to 7 in rune slice)
sub := string(r[6:7])
fmt.Println(sub) // Output: 🚀
}
For more complex extraction logic, such as finding a substring between two delimiters, use strings.Index to locate positions before slicing:
package main
import (
"fmt"
"strings"
)
func main() {
s := "user@example.com"
start := strings.Index(s, "@")
end := strings.Index(s, ".")
if start != -1 && end != -1 && end > start {
domain := s[start+1 : end]
fmt.Println(domain) // Output: example
}
}
Remember that string slicing in Go creates a new string that shares the underlying byte array with the original. If you need to modify the substring without affecting the original or if the original is very large, consider using strings.Builder or copying the data explicitly. Always check indices to avoid panic: runtime error: slice bounds out of range.