修剪字符串的后缀或扩展名?

问题描述 投票:0回答:8

例如,我有一个字符串,由“sample.zip”组成。如何使用字符串包或其他方式删除“.zip”扩展名?

string go
8个回答
284
投票

尝试:

basename := "hello.blah"
name := strings.TrimSuffix(basename, filepath.Ext(basename))

TrimSuffix 基本上告诉它去掉尾随字符串,即带点的扩展名。

字符串#TrimSuffix


99
投票

编辑: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 要在使用句点以外的扩展分隔符的理论操作系统上运行。


2
投票

这只是提高了一行的性能。在这里:

filename := strings.Split(file.Filename, ".")[0]

1
投票

这个方法也有效:

var filename = "hello.blah"
var extension = filepath.Ext(filename)
var name = TrimRight(filename, extension)

但也许 Paul Ruane 的方法更有效?


1
投票

我正在使用 go1.14.1,

filepath.Ext
不适合我,
path.Ext
适合我

var fileName = "hello.go"
fileExtension := path.Ext(fileName)
n := strings.LastIndex(fileName, fileExtension)
fmt.Println(fileName[:n])

游乐场:https://play.golang.org/p/md3wAq_obNc

文档:https://golang.org/pkg/path/#Ext


1
投票

这是不需要

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

https://golang.org/pkg/strings#LastIndexByte


0
投票

我一直在用这个:

name, _, _ := strings.Cut(fullName, ".")

它返回第一个点之前的任何内容,如果没有点,则返回整个字符串。


-1
投票

总结,包括多个扩展名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
© www.soinside.com 2019 - 2024. All rights reserved.