Golang中是否有类似Python的rsplit()函数?
Golang中是否有类似Python的rsplit()函数? 大家好,希望你们今天/今晚过得愉快。我正在尝试学习 Go 中 Split() 方法的工作原理,并且想知道 Go 中是否有类似 Python 中 rsplit() 的功能。
我一直在尝试的是获取用户输入,按空格分割,并将其存储到一个名为 ‘hey’ 的切片中,然后打印出来。我目前的代码如下:
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if text == "0" {
break
}
hey := strings.Split(text, " ")
fmt.Println(hey)
}
}
我期望用户输入的形式是:
城市名称 经度 纬度
在一行内。例如,如果用户输入:
London 185 86
那么 hey 切片将是 {London 185 86},这符合我的预期。
但问题是当用户输入一个带有空格的城市名称时,例如“Buenos Aires”。那么用户输入将类似于“Buenos Aires 185 86”。
在这种情况下,我希望 hey 切片是 {Buenos Aires 185 86},在 Go 中有没有好的方法来实现这一点?在 Python 中可以使用 rsplit(" ", 2) 来完成,但我已经搜索过并阅读了文档,却找不到类似的方法。有人能帮我解决这个问题吗?
更多关于Golang中是否有类似Python的rsplit()函数?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
非常感谢您的友好回复!
更多关于Golang中是否有类似Python的rsplit()函数?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
由于城市名称可能包含多个单词,也许更好的方法是读取单词并检查每个单词的类型(字符串或数字),然后仅连接字符串……
这听起来是个好主意,但我该怎么做呢?
我可能会这样做:
fields := strings.Fields("Buenos Aires 185 86")
for len(fields) > 3 {
fields[1] = fields[0] + " " + fields[1]
fields = fields[1:]
}
我脑海中快速闪过一个简单直接的解决方案,如下所示:
package main
import (
"fmt"
"strconv"
"strings"
)
const data = "Buenos Aires 185 86"
func main() {
var city string
var long, lat int
for i, fields := 0, strings.Fields(data); i < len(fields); i++ {
if _, err := strconv.Atoi(fields[i]); err != nil {
city = city + fields[i] + " "
continue
}
long, _ = strconv.Atoi(fields[i])
lat, _ = strconv.Atoi(fields[i+1])
city = city[:len(city)-1]
break
}
fmt.Printf("%s, [%d %d]\n", city, long, lat)
}
你也可以尝试一个更复杂的名称,例如 Edinburgh of the Seven Seas。
在Go标准库中没有直接对应Python rsplit()的函数,但可以通过组合现有函数实现相同功能。以下是几种解决方案:
方案1:使用strings.LastIndex()手动分割
func rsplit(s, sep string, n int) []string {
result := make([]string, 0, n+1)
for i := 0; i < n; i++ {
idx := strings.LastIndex(s, sep)
if idx == -1 {
break
}
result = append([]string{s[idx+len(sep):]}, result...)
s = s[:idx]
}
result = append([]string{s}, result...)
return result
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if text == "0" {
break
}
// 从右侧分割2次(对应Python的rsplit(" ", 2))
hey := rsplit(text, " ", 2)
fmt.Println(hey)
}
}
方案2:使用strings.Fields()和手动重组
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if text == "0" {
break
}
// 分割所有字段
fields := strings.Fields(text)
if len(fields) >= 3 {
// 最后两个元素是经度和纬度
lat := fields[len(fields)-1]
lon := fields[len(fields)-2]
// 剩余部分合并为城市名
city := strings.Join(fields[:len(fields)-2], " ")
hey := []string{city, lon, lat}
fmt.Println(hey)
} else {
fmt.Println(fields)
}
}
}
方案3:使用正则表达式
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 匹配:城市名(可能包含空格) + 空格 + 数字 + 空格 + 数字
re := regexp.MustCompile(`^(.+?)\s+(\d+)\s+(\d+)$`)
for scanner.Scan() {
text := scanner.Text()
if text == "0" {
break
}
matches := re.FindStringSubmatch(text)
if matches != nil {
hey := []string{matches[1], matches[2], matches[3]}
fmt.Println(hey)
} else {
fmt.Println("格式错误")
}
}
}
方案4:使用strings.SplitN()配合反转(最接近Python rsplit逻辑)
func reverseSplit(s, sep string, n int) []string {
// 先分割成多个部分
parts := strings.Split(s, sep)
if len(parts) <= n {
return parts
}
// 从右侧开始分组
result := make([]string, n+1)
// 最后n个元素单独放置
for i := 0; i < n; i++ {
result[n-i] = parts[len(parts)-1-i]
}
// 剩余部分合并为第一个元素
result[0] = strings.Join(parts[:len(parts)-n], sep)
return result
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if text == "0" {
break
}
hey := reverseSplit(text, " ", 2)
fmt.Println(hey)
}
}
对于你的具体用例(城市名 经度 纬度),方案2最简单实用。如果需要更通用的rsplit功能,方案1或方案4提供了可重用的函数。

