Extracting substrings in Go
GoSubstringGo Problem Overview
I'm trying to read an entire line from the console (including whitespace), then process it. Using bufio.ReadString, the newline character is read together with the input, so I came up with the following code to trim the newline character:
input,_:=src.ReadString('\n')
inputFmt:=input[0:len(input)-2]+"" //Need to manually add end of string
Is there a more idiomatic way to do this? That is, is there already a library that takes care of the ending null byte when extracting substrings for you?
(Yes, I know there is already a way to read a line without the newline character in https://stackoverflow.com/questions/6141604/go-readline-string but I'm looking more for elegant string manipulation.)
Go Solutions
Solution 1 - Go
It looks like you're confused by the working of slices and the string storage format, which is different from what you have in C.
- any slice in Go stores the length (in bytes), so you don't have to care about the cost of the
len
operation : there is no need to count - Go strings aren't null terminated, so you don't have to remove a null byte, and you don't have to add
1
after slicing by adding an empty string.
To remove the last char (if it's a one byte char), simply do
inputFmt:=input[:len(input)-1]
Solution 2 - Go
WARNING: operating on strings alone will only work with ASCII and will count wrong when input is a non-ASCII UTF-8 encoded character, and will probably even corrupt characters since it cuts multibyte chars mid-sequence.
Here's a UTF-8-aware version:
// NOTE: this isn't multi-Unicode-codepoint aware, like specifying skintone or
// gender of an emoji: https://unicode.org/emoji/charts/full-emoji-modifiers.html
func substr(input string, start int, length int) string {
asRunes := []rune(input)
if start >= len(asRunes) {
return ""
}
if start+length > len(asRunes) {
length = len(asRunes) - start
}
return string(asRunes[start : start+length])
}
Solution 3 - Go
Go strings are not null terminated, and to remove the last char of a string you can simply do:
s = s[:len(s)-1]
Solution 4 - Go
This is the simple one to perform substring in Go
package main
import "fmt"
var p = fmt.Println
func main() {
value := "address;bar"
// Take substring from index 2 to length of string
substring := value[2:len(value)]
p(substring)
}
Solution 5 - Go
To avoid a panic on a zero length input, wrap the truncate operation in an if
input, _ := src.ReadString('\n')
var inputFmt string
if len(input) > 0 {
inputFmt = input[:len(input)-1]
}
// Do something with inputFmt
Solution 6 - Go
To get substring
-
find position of "sp"
-
cut string with array-logical
Solution 7 - Go
8 years later I stumbled upon this gem, and yet I don't believe OP's original question was really answered:
> so I came up with the following code to trim the newline character
While the bufio.Reader
type supports a ReadLine()
method which both removes \r\n
and \n
it is meant as a low-level function which is awkward to use because repeated checks are necessary.
IMO an idiomatic way to remove whitespace is to use Golang's strings library:
input, _ = src.ReadString('\n')
// more specific to the problem of trailing newlines
actual = strings.TrimRight(input, "\r\n")
// or if you don't mind to trim leading and trailing whitespaces
actual := strings.TrimSpace(input)
See this example in action in the Golang playground: https://play.golang.org/p/HrOWH0kl3Ww
Solution 8 - Go
Hope this function will be helpful for someone,
str := "Error 1062: Duplicate entry '[email protected]' for key 'users.email'"
getViolatedValue(str)
This is used to substring that used ' in the main string
func getViolatedValue(msg string) string {
i := strings.Index(msg, "'")
if i > -1 {
part := msg[i+1:]
j := strings.Index(part, "'")
if j > -1 {
return part[:j]
}
return ""
} else {
return ""
}
}