在Go中提取子字符串


114

我正在尝试从控制台(包括空格)读取整行,然后对其进行处理。使用bufio.ReadString,将换行符与输入一起读取,因此我想出了以下代码来修剪换行符:

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

有没有更惯用的方法来做到这一点?也就是说,是否已经有一个库在为您提取子字符串时处理结尾的空字节?

(是的,我知道在go readline-> string中已经有一种不用换行符就能读取行的方法,但是我正在寻找更多用于优雅的字符串操作的方法。)

Answers:


146

看起来您对切片和字符串存储格式的工作感到困惑,这与您在C语言中所拥有的有所不同。

  • Go中的任何切片都存储长度(以字节为单位),因此您不必担心len操作成本:无需计数
  • Go字符串不是以null终止的,因此您不必删除一个null字节,也不必1在切片后通过添加空字符串来添加。

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

inputFmt:=input[:len(input)-1]

11
您甚至不需要0(或:)s = s[:len(s)-1]就可以了。
uriel 2012年

1
非常感谢您的澄清;从ReadString函数返回的字符串的末尾似乎有两个空格字符,因此我误认为一个为空字节。很抱歉与C字符串混淆;我将fmt和bufio一起使用,导致控制台中出现有趣的内容,因此我认为这可能是肮脏的null字节。只是最后的澄清-ReadString中多余的空格是什么?
mark2222 2012年

好的,我将回答我自己的问题-它是\ r然后\ n:P有趣的控制台输出是因为我输出的\ r没有\ n。
mark2222 2012年

8
请注意,此方法不适用于Unicode字符串!groups.google.com/forum/#!msg/golang-nuts/ZeYei0IWrLg/…–
Melllvar

@Melllvar这就是为什么我精确地说“如果是一个字节的char”。如果要删除一个多于一个字节的字符(不是OP的情况),则必须适应。
DenysSéguret13年

25

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

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

10
这是不正确的,并且会导致错误。这会从字符串中删除最后一个字节,这可能使其变为无效的UTF-8(或其他多字节编码)。
博士 Sybren

3
有关如何中断的示例,请参见play.golang.org/p/K3HBBtj4Oi
博士 Sybren

10

为避免零长度输入出现恐慌,请将截断操作包装在if中

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

9

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

}

7

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

这是可识别UTF-8的版本:

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

1
这需要更多的投票方式-我只是因为不使用utf-8感知拆分而被严重咬伤。
kolaente


2

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)

请在Golang游乐场中查看实际操作中的示例:https : //play.golang.org/p/HrOWH0kl3Ww

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.