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

huangapple go评论85阅读模式
英文:

Trim string's suffix or extension?

问题

例如,我有一个字符串,包含"sample.zip"。我如何使用strings包或其他方法删除".zip"扩展名?

英文:

For example, I have a string, consists of "sample.zip". How do I remove the ".zip" extension using strings package or other else?

答案1

得分: 273

尝试:

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

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

strings#TrimSuffix

英文:

Try:

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

TrimSuffix basically tells it to strip off the trailing string which is the extension with a dot.

strings#TrimSuffix

答案2

得分: 99

使用path/filepath.Ext来获取文件扩展名。然后,您可以使用扩展名的长度来获取不包含扩展名的子字符串。

var filename = "hello.blah"
var extension = filepath.Ext(filename)
var name = filename[0:len(filename)-len(extension)]

或者,您可以使用strings.LastIndex来找到最后一个句点(.),但这可能会更加脆弱,因为会有一些边缘情况(例如没有扩展名)需要您显式编码处理,或者如果Go在一个理论上使用其他扩展名分隔符的操作系统上运行。

英文:

Edit: Go has moved on. Please see Keith's answer.

Use path/filepath.Ext to get the extension. You can then use the length of the extension to retrieve the substring minus the extension.

var filename = "hello.blah"
var extension = filepath.Ext(filename)
var name = filename[0:len(filename)-len(extension)]

Alternatively you could use strings.LastIndex to find the last period (.) but this may be a little more fragile in that there will be edge cases (e.g. no extension) that filepath.Ext handles that you may need to code for explicitly, or if Go were to be run on a theoretical O/S that uses a extension delimiter other than the period.

答案3

得分: 3

这只是一行更高效的代码。这里是:

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

This is just one line more performant. Here it is:

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

答案4

得分: 2

这种方法也可以:

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

但是也许Paul Ruane的方法更高效?

英文:

This way works too:

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

but maybe Paul Ruane's method is more efficient?

答案5

得分: 2

我正在使用go1.14.1,filepath.Ext对我无效,path.Ext对我有效。

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

Playground: https://play.golang.org/p/md3wAq_obNc

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

英文:

I am using go1.14.1, filepath.Ext did not work for me, path.Ext works fine for me

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

Playground: https://play.golang.org/p/md3wAq_obNc

Documnetation: https://golang.org/pkg/path/#Ext

答案6

得分: 2

这是一个不需要pathpath/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

英文:

Here is example that does not require path or path/filepath:

func BaseName(s string) string {
   n := strings.LastIndexByte(s, '.')
   if n == -1 { return s }
   return s[:n]
}

and it seems to be faster than TrimSuffix as well:

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

答案7

得分: 0

Summary, including the case of multiple extension names abc.tar.gz and performance comparison.

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

run cmd: go test temp_test.go -v -bench="^BenchmarkGetPureBasename" -run=TestGetBasenameWithoutExt

output

=== 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
英文:

Summary, including the case of multiple extension names <sup>abc.tar.gz</sup> and performance comparison.

temp_test.go

package _test
import (&quot;fmt&quot;;&quot;path/filepath&quot;;&quot;strings&quot;;&quot;testing&quot;;)
func TestGetBasenameWithoutExt(t *testing.T) {
	p1 := &quot;abc.txt&quot;
	p2 := &quot;abc.tar.gz&quot; // filepath.Ext(p2) return `.gz`
	for idx, d := range []struct {
		actual   interface{}
		expected interface{}
	}{
		{fmt.Sprint(p1[:len(p1)-len(filepath.Ext(p1))]), &quot;abc&quot;},
		{fmt.Sprint(strings.TrimSuffix(p1, filepath.Ext(p1))), &quot;abc&quot;},
		{fmt.Sprint(strings.TrimSuffix(p2, filepath.Ext(p2))), &quot;abc.tar&quot;},
		{fmt.Sprint(p2[:len(p2)-len(filepath.Ext(p2))]), &quot;abc.tar&quot;},
		{fmt.Sprint(p2[:len(p2)-len(&quot;.tar.gz&quot;)]), &quot;abc&quot;},
	} {
		if d.actual != d.expected {
			t.Fatalf(&quot;[Error] case: %d&quot;, idx)
		}
	}
}

func BenchmarkGetPureBasenameBySlice(b *testing.B) {
	filename := &quot;abc.txt&quot;
	for i := 0; i &lt; b.N; i++ {
		_ = filename[:len(filename)-len(filepath.Ext(filename))]
	}
}

func BenchmarkGetPureBasenameByTrimSuffix(b *testing.B) {
	filename := &quot;abc.txt&quot;
	for i := 0; i &lt; b.N; i++ {
		_ = strings.TrimSuffix(filename, filepath.Ext(filename))
	}
}

run cmd: go test temp_test.go -v -bench=&quot;^BenchmarkGetPureBasename&quot; -run=TestGetBasenameWithoutExt

output

=== 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

huangapple
  • 本文由 发表于 2012年10月23日 17:57:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/13027912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定