在Go中提取子串

mar*_*222 96 substring go

我试图从控制台(包括空格)读取整行,然后处理它.使用bufio.ReadString,换行字符与输入一起读取,所以我想出了以下代码来修剪换行符:

input,_:=src.ReadString('\n')
inputFmt:=input[0:len(input)-2]+"" //Need to manually add end of string
Run Code Online (Sandbox Code Playgroud)

有没有比较惯用的方法呢?也就是说,在为您提取子字符串时,是否已有一个处理结束空字节的库?

(是的,我知道有一种方法可以在go readline - > string中读取没有换行符的行,但我正在寻找更优雅的字符串操作.)

Den*_*ret 121

看起来你对切片的工作和字符串存储格式感到困惑,这与你在C中的不同.

  • Go中的任何切片都存储长度(以字节为单位),因此您不必关心len操作的成本:无需计算
  • Go字符串不是以null结尾,因此您不必删除空字节,也不必1在切片后添加空字符串.

要删除最后一个char(如果它是一个字节的char),只需执行

inputFmt:=input[:len(input)-1]
Run Code Online (Sandbox Code Playgroud)

  • 你甚至不需要0(或:),`s = s [:len(s)-1]`会这样做. (10认同)
  • 请注意,此方法不适用于Unicode字符串!https://groups.google.com/forum/#!msg/golang-nuts/ZeYei0IWrLg/PfPnAy_TVsMJ (6认同)
  • @Melllvar 这就是为什么我精确地*“如果它是一个单字节字符”*。如果你想删除一个占用超过一个字节的字符(这不是OP的情况),你必须适应。 (2认同)
  • @FiftiN 这个答案适用于大多数情况,甚至是 UTF-8,只要您不将其视为字符索引即可。例如,UTF-8 的设计方式是,您可以通过字节比较来搜索子字符串,如果您搜索某些内容,然后使用它来获取子字符串,则一切都会正常进行,尽管它没有明确意识到 UTF-8,因为制作UTF-8的人足够聪明 (2认同)

joo*_*.fi 38

警告:单独对字符串进行操作仅适用于 ASCII,并且当输入是非 ASCII UTF-8 编码字符时会计算错误,甚至可能会损坏字符,因为它会在中间序列中切割多字节字符。

这是一个支持 UTF-8 的版本:

// 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])
}
Run Code Online (Sandbox Code Playgroud)

  • 这需要更多的支持 - 我刚刚因为不使用 utf-8 感知分割而受到严重影响。 (4认同)
  • 这实际上也不起作用,在某些情况下,只有一系列符文组成一个符号,例如国旗的表情符号由两个符文表示。你真的想把它切成两半吗?我想默认情况下没有给出这样的函数是有原因的:没有通用的正确方法可以在没有上下文的情况下分割 unicode 字符串。除此之外,如果您使用基于通过搜索子字符串获得的索引的子字符串,则不需要使用支持 UTF-8 的子字符串函数;UTF-8 的设计方式甚至可以与二进制函数一起使用 (2认同)

uri*_*iel 21

Go字符串不是以null结尾,并且要删除字符串的最后一个字符,您可以简单地执行:

s = s[:len(s)-1]
Run Code Online (Sandbox Code Playgroud)

  • 这是不正确的,会导致错误.这会剥离字符串中的最后一个*字节*,这可能使其无效UTF-8(或其他多字节编码). (7认同)
  • 有关如何中断的示例,请参阅https://play.golang.org/p/K3HBBtj4Oi. (3认同)

Roh*_*wiz 9

为避免零长度输入发生混乱,请将截断操作包装在if中

input, _ := src.ReadString('\n')
var inputFmt string
if len(input) > 0 {
    inputFmt = input[:len(input)-1]
}
// Do something with inputFmt
Run Code Online (Sandbox Code Playgroud)


Far*_*han 5

这是在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)

}
Run Code Online (Sandbox Code Playgroud)


小智 5

8 年后,我偶然发现了这颗宝石,但我不相信 OP 最初的问题得到了真正的回答:

所以我想出了以下代码来修剪换行符

虽然该bufio.Reader类型支持一种ReadLine() 既可以删除\r\n\n可以作为低级函数的方法,但由于需要重复检查,因此使用起来很困难。

IMO 删除空格的惯用方法是使用 Golang 的字符串库:

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)
Run Code Online (Sandbox Code Playgroud)

请参阅 Golang Playground 中的实际示例:https://play.golang.org/p/HrOWH0kl3Ww