mark2222
mark2222

Reputation: 2117

Extracting substrings in Go

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 go readline -> string but I'm looking more for elegant string manipulation.)

Upvotes: 200

Views: 392001

Answers (9)

user3413723
user3413723

Reputation: 12233

Not too hard:

str := "😄♥️👍"
substr := string([]rune(str)[1:2])
print(substr) // outputs ♥️

It's important to use this method with runes, as it's utf-8 aware (that's why I used emojis for testing)

Upvotes: 0

Faris Rayhan
Faris Rayhan

Reputation: 4636

This is the simple one to perform substring in Go

package main

import "fmt"

func main() {

  value := "address;bar"

  // Take substring from index 2 to length of string
  substring := value[2:len(value)]
  fmt.Println(substring)

}

Upvotes: 18

Thushara Buddhika
Thushara Buddhika

Reputation: 1820

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 ""
    }
}

Upvotes: 2

joonas.fi
joonas.fi

Reputation: 8226

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])
}

Upvotes: 105

Philipp Pixel
Philipp Pixel

Reputation: 178

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

Upvotes: 5

Denys Séguret
Denys Séguret

Reputation: 382150

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]

Upvotes: 252

TeeTracker
TeeTracker

Reputation: 7350

To get substring

  1. find position of "sp"

  2. cut string with array-logical

https://play.golang.org/p/0Redd_qiZM

Upvotes: 3

Rohanthewiz
Rohanthewiz

Reputation: 975

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

Upvotes: 10

uriel
uriel

Reputation: 1473

Go strings are not null terminated, and to remove the last char of a string you can simply do:

s = s[:len(s)-1]

Upvotes: 29

Related Questions