如何移除字符串的第一个字符是什么建议方法?
我查看了字符串方法的文档,但没有发现类似JavaScript中的String.slice()的任何方法适用。
假设问题中使用“字符”来指代Go语言中的rune,那么可以使用utf8.DecodeRuneInString获取第一个符文的大小,然后进行切片:
func trimFirstRune(s string) string {
_, i := utf8.DecodeRuneInString(s)
return s[i:]
}
正如peterSO在他的评论中提到的链接游乐场示例所示,字符串范围也可以用于找到第一个符文结束的位置:
func trimFirstRune(s string) string {
for i := range s {
if i > 0 {
// The value i is the index in s of the second
// rune. Slice to remove the first rune.
return s[i:]
}
}
// There are 0 or 1 runes in the string.
return ""
}
trimFirstRune
是正确的,但它似乎比 trimLeftChar
和 trimLeftChars
效率低:https://play.golang.org/p/ZOZyRORkK82。请参阅 utf8.DecodeRuneInString
的源代码。 - peterSO这个方法对我有效:
package main
import "fmt"
func main() {
input := "abcd"
fmt.Println(input[1:])
}
输出结果为:
bcd
在 Go Playground 上的代码: https://play.golang.org/p/iTv7RpML3LO
input := "µabcd"
时会发生什么。 - mu is too shortµ
这样的Unicode字符。下次我会记住的。 - Vikram Hosakote在Go语言中,字符 string
是以UTF-8编码的Unicode代码点表示的。UTF-8是一种可变长度的编码方式。
带有range子句的For语句:
对于字符串值,"range"子句从字节索引0开始迭代字符串中的Unicode代码点。在后续迭代中,索引值将是字符串中连续的UTF-8编码代码点的第一个字节的索引值,而第二个值,类型为rune,将是相应代码点的值。如果迭代遇到无效的UTF-8序列,则第二个值将是0xFFFD(Unicode替换字符),并且下一次迭代将在字符串中前进一个字节。
例如,
package main
import "fmt"
func trimLeftChar(s string) string {
for i := range s {
if i > 0 {
return s[i:]
}
}
return s[:0]
}
func main() {
fmt.Printf("%q\n", "Hello, 世界")
fmt.Printf("%q\n", trimLeftChar(""))
fmt.Printf("%q\n", trimLeftChar("H"))
fmt.Printf("%q\n", trimLeftChar("世"))
fmt.Printf("%q\n", trimLeftChar("Hello"))
fmt.Printf("%q\n", trimLeftChar("世界"))
}
游乐场:https://play.golang.org/p/t93M8keTQP_I
输出:
"Hello, 世界"
""
""
""
"ello"
"界"
或者,对于一个更一般的函数:
package main
import "fmt"
func trimLeftChars(s string, n int) string {
m := 0
for i := range s {
if m >= n {
return s[i:]
}
m++
}
return s[:0]
}
func main() {
fmt.Printf("%q\n", trimLeftChars("", 1))
fmt.Printf("%q\n", trimLeftChars("H", 1))
fmt.Printf("%q\n", trimLeftChars("世", 1))
fmt.Printf("%q\n", trimLeftChars("Hello", 1))
fmt.Printf("%q\n", trimLeftChars("世界", 1))
fmt.Println()
fmt.Printf("%q\n", "Hello, 世界")
fmt.Printf("%q\n", trimLeftChars("Hello, 世界", 0))
fmt.Printf("%q\n", trimLeftChars("Hello, 世界", 1))
fmt.Printf("%q\n", trimLeftChars("Hello, 世界", 7))
fmt.Printf("%q\n", trimLeftChars("Hello, 世界", 8))
fmt.Printf("%q\n", trimLeftChars("Hello, 世界", 9))
fmt.Printf("%q\n", trimLeftChars("Hello, 世界", 10))
}
游乐场: https://play.golang.org/p/ECAHl2FqdhR
输出:
""
""
""
"ello"
"界"
"Hello, 世界"
"Hello, 世界"
"ello, 世界"
"世界"
"界"
""
""
参考文献:
⚕️
这样的符号会很难处理。请注意,我不是吹毛求疵,我知道这是一个复杂的问题,不确定是否能用少于几十/几百千字节的代码来解决它。 - zerkmstrimLeftChars(s, 1)
应该完全将其删除。(如果您使用 Linux,请尝试使用最新操作系统的手机或其他操作系统(Windows/Mac)查看是否正确呈现-这些4个代码点将合并为单个字形) - zerkmsutf8string
包:package main
import "golang.org/x/exp/utf8string"
func main() {
s := utf8string.NewString("")
t := s.Slice(1, s.RuneCount())
println(t == "")
}
这是我找到的最佳的一行解决方案,使用了strings包,适用于这个使用场合。
package main
import (
"fmt"
"strings"
)
func main() {
myString1 := "/abc/def"
myString2 := "Hello World"
myString3 := "HHello World"
fmt.Println(strings.TrimPrefix(myString1, "/"))
fmt.Println(strings.TrimPrefix(myString2, "/"))
fmt.Println(strings.TrimPrefix(myString3, "H"))
}
abc/def
Hello World
Hello World
Go Playground链接: https://go.dev/play/p/tt3GgDjHXFg?v=goprev
您可以将字符串转换为字符数组,弹出第一个字符并将数组转换回字符串。这是一行代码:
str = string([]rune(str)[1:])
str[1:]
就可以解决问题。 - zerkms"µñ"[1:]
不能完全按预期工作。 - mu is too short