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 \n
s. First, this swaps '
and "
, and changes \n
s to actual newlines. Then it strconv.Unquote
s 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])
}