24

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.

RamaRaunt
  • 379
  • 1
  • 2
  • 8

5 Answers5

40

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

Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • Why do `len(s)` twice? Why not nest it like so?: `if len(s) { if s[0] == '"' { s = s[1:] } if s[len(s)-1] == '"' { s = s[:len(s)-1] } }` – apokaliptis Oct 13 '21 at 19:54
  • @apokaliptis The answer checks len(s) twice to handle the input `"`. – Charlie Tumahai Oct 13 '21 at 22:46
  • I tried both these approcehes for rederning a string in a html template and in both ceases they removed the result still had the quote in it; i.e.

    "his is the string with quotes yet missing the first and last characte"

    – Alan Carlyle Nov 21 '21 at 09:29
  • @AlanCarlyle: It looks like (a) you used first approach that removes the first and last byte from the string, no matter what those bytes are (b) the template is adding quotes. You should ask a new question if you have not figured out what's wrong with your program. – Charlie Tumahai Nov 21 '21 at 15:01
  • @CeriseLimón I'm fairly sure the go html/template is adding the quotes itself as I know I'm not doing putting them in the sting. I've had a hunt for answers to the problem and most have just dealt with how to escape quotes in html so the display. – Alan Carlyle Nov 22 '21 at 12:24
13

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

Rahul Satal
  • 2,107
  • 3
  • 32
  • 53
3

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`
peterSO
  • 158,998
  • 31
  • 281
  • 276
2

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.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • @CeriseLimón Thanks, I'm still learning the relationship between string and []byte. I had a page that explained when a copy would happen and when it wouldn't, but I've misplaced it. Do you have a resource? – Schwern May 28 '17 at 04:22
0

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.

Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173