例如,我有一个字符串,由“sample.zip”组成。如何使用字符串包或其他方式删除“.zip”扩展名?
尝试:
basename := "hello.blah"
name := strings.TrimSuffix(basename, filepath.Ext(basename))
TrimSuffix 基本上告诉它去掉尾随字符串,即带点的扩展名。
编辑:Go 已经继续前进。请参阅Keith的回答。
使用 path/filepath.Ext 获取扩展名。然后,您可以使用扩展名的长度来检索减去扩展名的子字符串。
var filename = "hello.blah"
var extension = filepath.Ext(filename)
var name = filename[0:len(filename)-len(extension)]
或者,您可以使用 strings.LastIndex 查找最后一个句点 (.),但这可能有点脆弱,因为存在
filepath.Ext
处理的边缘情况(例如,无扩展名),您可能需要编写代码明确地,或者如果 Go 要在使用句点以外的扩展分隔符的理论操作系统上运行。
这只是提高了一行的性能。在这里:
filename := strings.Split(file.Filename, ".")[0]
这个方法也有效:
var filename = "hello.blah"
var extension = filepath.Ext(filename)
var name = TrimRight(filename, extension)
但也许 Paul Ruane 的方法更有效?
我正在使用 go1.14.1,
filepath.Ext
不适合我,path.Ext
适合我
var fileName = "hello.go"
fileExtension := path.Ext(fileName)
n := strings.LastIndex(fileName, fileExtension)
fmt.Println(fileName[:n])
这是不需要
path
或 path/filepath
的示例:
func BaseName(s string) string {
n := strings.LastIndexByte(s, '.')
if n == -1 { return s }
return s[:n]
}
而且它似乎也比
TrimSuffix
更快:
PS C:\> go test -bench .
goos: windows
goarch: amd64
BenchmarkTrimFile-12 166413693 7.25 ns/op
BenchmarkTrimPath-12 182020058 6.56 ns/op
BenchmarkLast-12 367962712 3.28 ns/op
我一直在用这个:
name, _, _ := strings.Cut(fullName, ".")
它返回第一个点之前的任何内容,如果没有点,则返回整个字符串。
总结,包括多个扩展名abc.tar.gz的情况以及性能对比。
temp_test.go
package _test
import ("fmt";"path/filepath";"strings";"testing";)
func TestGetBasenameWithoutExt(t *testing.T) {
p1 := "abc.txt"
p2 := "abc.tar.gz" // filepath.Ext(p2) return `.gz`
for idx, d := range []struct {
actual interface{}
expected interface{}
}{
{fmt.Sprint(p1[:len(p1)-len(filepath.Ext(p1))]), "abc"},
{fmt.Sprint(strings.TrimSuffix(p1, filepath.Ext(p1))), "abc"},
{fmt.Sprint(strings.TrimSuffix(p2, filepath.Ext(p2))), "abc.tar"},
{fmt.Sprint(p2[:len(p2)-len(filepath.Ext(p2))]), "abc.tar"},
{fmt.Sprint(p2[:len(p2)-len(".tar.gz")]), "abc"},
} {
if d.actual != d.expected {
t.Fatalf("[Error] case: %d", idx)
}
}
}
func BenchmarkGetPureBasenameBySlice(b *testing.B) {
filename := "abc.txt"
for i := 0; i < b.N; i++ {
_ = filename[:len(filename)-len(filepath.Ext(filename))]
}
}
func BenchmarkGetPureBasenameByTrimSuffix(b *testing.B) {
filename := "abc.txt"
for i := 0; i < b.N; i++ {
_ = strings.TrimSuffix(filename, filepath.Ext(filename))
}
}
运行cmd:
go test temp_test.go -v -bench="^BenchmarkGetPureBasename" -run=TestGetBasenameWithoutExt
输出
=== RUN TestGetBasenameWithoutExt
--- PASS: TestGetBasenameWithoutExt (0.00s)
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
BenchmarkGetPureBasenameBySlice
BenchmarkGetPureBasenameBySlice-8 356602328 3.125 ns/op
BenchmarkGetPureBasenameByTrimSuffix
BenchmarkGetPureBasenameByTrimSuffix-8 224211643 5.359 ns/op
PASS