Golang : Escaping single quotes - go

Is there a way to escape single quotes in go?
The following:
str := "I'm Bob, and I'm 25."
str = strings.Replace(str, "'", "\'", -1)
Gives the error: unknown escape sequence: '
I would like str to be
"I\'m Bob, and I\'m 25."

You need to ALSO escape the slash in strings.Replace.
str := "I'm Bob, and I'm 25."
str = strings.ReplaceAll(str, "'", "\\'")
https://play.golang.org/p/BPtU2r8dXrs

+to #KeylorSanchez answer: your can wrap replace string in back-ticks:
strings.ReplaceAll(str, "'", `\'`)

// addslashes()
func Addslashes(str string) string {
var buf bytes.Buffer
for _, char := range str {
switch char {
case '\'':
buf.WriteRune('\\')
}
buf.WriteRune(char)
}
return buf.String()
}
If you want to escaping single/double quotes or backlash, you can refer to https://github.com/syyongx/php2go

Related

How to split a string by a delimiter in Golang

I want to split a string by a delimiter, and the result should be a slice.
For example:
The given string might be like this:
foo := "foo=1&bar=2&&a=8"
The result should be like
result := []string{
"foo=1",
"bar=2&",
"a=8"
}
I mean i can use strings.split(foo, "&") to split but the result does not meet my requirements.
// the result with strings.split()
result := []string{
"foo=1",
"bar=2",
"",
"a=8"
}
Why not use url.ParseQuery. If you need a special characters like & (which is the delimiter) to not be treated as such, then it needs to be escaped (%26):
//m, err := url.ParseQuery("foo=1&bar=2&&a=8")
m, err := url.ParseQuery("foo=1&bar=2%26&a=8") // escape bar's & as %26
fmt.Println(m) // map[a:[8] bar:[2&] foo:[1]]
https://play.golang.org/p/zG3NEL70HxE
You would typically URL encode parameters like so:
q := url.Values{}
q.Add("foo", "1")
q.Add("bar", "2&")
q.Add("a", "8")
fmt.Println(q.Encode()) // a=8&bar=2%26&foo=1
https://play.golang.org/p/hSdiLtgVj7m

more than one character in rune literal

I have a string as just MyString and I want to append in this data something like this:
MYString ("1", "a"), ("1", "b") //END result
My code is something like this:
query := "MyString";
array := []string{"a", "b"}
for i , v := range array{
id := "1"
fmt.Println(v,i)
query += '("{}", "{}"), '.format(id, v)
}
but I am getting two errors:
./prog.go:15:23: more than one character in rune literal
./prog.go:15:39: '\u0000'.format undefined (type rune has no field or method format)
You can't use single quotes for Strings in Go. You can only use double-quotes or backticks.
Single quotes are used for single characters, called runes
Change your line to:
query += "(\"{}\", \"{}\"), ".format(id, v)
or
query += `("{}", "{}"), `.format(id, v)
However, Go is not python. Go doesn't have a format method like that. But it has fmt.Sprintf.
So to really fix it, use:
query = fmt.Sprintf(`%s("%s", "%s"), `, query, id, v)
Issue here is single quotes . Go Compiler expects a character only when encounters '' . Rather use double quotes with escape symbol as explained in above example.

How to escape a string with single quotes

I am trying to unquote a string that uses single quotes in Go (the syntax is same as Go string literal syntax but using single quotes not double quotes):
'\'"Hello,\nworld!\r\n\u1F60ANice to meet you!\nFirst Name\tJohn\nLast Name\tDoe\n'
should become
'"Hello,
world!
😊Nice to meet you!
First Name John
Last Name Doe
How do I accomplish this?
strconv.Unquote doesn't work on \n newlines (https://github.com/golang/go/issues/15893 and https://golang.org/pkg/strconv/#Unquote), and simply strings.ReplaceAll(ing would be a pain to support all Unicode code points and other backslash codes like \n & \r & \t.
I may be asking for too much, but it would be nice if it automatically validates the Unicode like how strconv.Unquote might be able to do/is doing (it knows that x Unicode code points may become one character), since I can do the same with unicode/utf8.ValidString.
#CeriseLimón came up with this answer, and I just put it into a function with more shenanigans to support \ns. First, this swaps ' and ", and changes \ns to actual newlines. Then it strconv.Unquotes each line, since strconv.Unquote cannot handle newlines, and then reswaps ' and " and pieces them together.
func unquote(s string) string {
replaced := strings.NewReplacer(
`'`,
`"`,
`"`,
`'`,
`\n`,
"\n",
).Replace(s[1:len(s)-1])
unquoted := ""
for _, line := range strings.Split(replaced, "\n") {
tmp, err := strconv.Unquote(`"` + line + `"`)
repr.Println(line, tmp, err)
if err != nil {
return nil, NewInvalidAST(obj.In.Text.LexerInfo, "*Obj.In.Text.Text")
}
unquoted += tmp + "\n"
}
return strings.NewReplacer(
`"`,
`'`,
`'`,
`"`,
).Replace(unquoted[:len(unquoted)-1])
}

Escape unicode characters in json encode golang

Given the following example:
func main() {
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
toEncode := []string{"hello", "wörld"}
enc.Encode(toEncode)
fmt.Println(buf.String())
}
I would like to have the output presented with escaped Unicode characters:
["hello","w\u00f6rld"]
Rather than:
["hello","wörld"]
I have attempted to write a function to quote the Unicode characters using strconv.QuoteToASCII and feed the results to Encode() however that results in double escaping:
func quotedUnicode(data []string) []string {
for index, element := range data {
quotedUnicode := strconv.QuoteToASCII(element)
// get rid of additional quotes
quotedUnicode = strings.TrimSuffix(quotedUnicode, "\"")
quotedUnicode = strings.TrimPrefix(quotedUnicode, "\"")
data[index] = quotedUnicode
}
return data
}
["hello","w\\u00f6rld"]
How can I ensure that the output from json.Encode contains correctly escaped Unicode characters?

How to remove quotes from around a string in Golang

I have a string in Golang that is surrounded by quote marks. My goal is to remove all quote marks on the sides, but to ignore all quote marks in the interior of the string. How should I go about doing this? My instinct tells me to use a RemoveAt function like in C#, but I don't see anything like that in Go.
For instance:
"hello""world"
should be converted to:
hello""world
For further clarification, this:
"""hello"""
would become this:
""hello""
because the outer ones should be removed ONLY.
Use a slice expression:
s = s[1 : len(s)-1]
If there's a possibility that the quotes are not present, then use this:
if len(s) > 0 && s[0] == '"' {
s = s[1:]
}
if len(s) > 0 && s[len(s)-1] == '"' {
s = s[:len(s)-1]
}
playground example
strings.Trim() can be used to remove the leading and trailing whitespace from a string. It won't work if the double quotes are in between the string.
// strings.Trim() will remove all the occurrences from the left and right
s := `"""hello"""`
fmt.Println("Before Trim: " + s) // Before Trim: """hello"""
fmt.Println("After Trim: " + strings.Trim(s, "\"")) // After Trim: hello
// strings.Trim() will not remove any occurrences from inside the actual string
s2 := `""Hello" " " "World""`
fmt.Println("\nBefore Trim: " + s2) // Before Trim: ""Hello" " " "World""
fmt.Println("After Trim: " + strings.Trim(s2, "\"")) // After Trim: Hello" " " "World
Playground link - https://go.dev/play/p/yLdrWH-1jCE
Use slice expressions. You should write robust code that provides correct output for imperfect input. For example,
package main
import "fmt"
func trimQuotes(s string) string {
if len(s) >= 2 {
if s[0] == '"' && s[len(s)-1] == '"' {
return s[1 : len(s)-1]
}
}
return s
}
func main() {
tests := []string{
`"hello""world"`,
`"""hello"""`,
`"`,
`""`,
`"""`,
`goodbye"`,
`"goodbye"`,
`goodbye"`,
`good"bye`,
}
for _, test := range tests {
fmt.Printf("`%s` -> `%s`\n", test, trimQuotes(test))
}
}
Output:
`"hello""world"` -> `hello""world`
`"""hello"""` -> `""hello""`
`"` -> `"`
`""` -> ``
`"""` -> `"`
`goodbye"` -> `goodbye"`
`"goodbye"` -> `goodbye`
`goodbye"` -> `goodbye"`
`good"bye` -> `good"bye`
You can take advantage of slices to remove the first and last element of the slice.
package main
import "fmt"
func main() {
str := `"hello""world"`
if str[0] == '"' {
str = str[1:]
}
if i := len(str)-1; str[i] == '"' {
str = str[:i]
}
fmt.Println( str )
}
Since a slice shares the underlying memory, this does not copy the string. It just changes the str slice to start one character over, and end one character sooner.
This is how the various bytes.Trim functions work.
A one-liner using regular expressions...
quoted = regexp.MustCompile(`^"(.*)"$`).ReplaceAllString(quoted,`$1`)
But it doesn't necessarily handle escaped quotes they way you might want.
The Go Playground
Translated from here.

Resources