如何在Go语言中将字符串中的多个斜杠(///)替换为一个斜杠(/)?

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

How to replace multiple slashes (///) in a string to one slash (/) in Go lang?

问题

"/hello/stackover.flow"

英文:

Input string: "///hello//stackover.flow"

Expected output: "/hello/stackover.flow"

答案1

得分: 7

你可以使用path.Clean来实现这个功能。

func Clean(path string) string

Clean函数通过纯粹的词法处理返回与路径path等效的最短路径名。它按照以下规则迭代应用,直到无法进行进一步处理为止:

  1. 将多个斜杠替换为单个斜杠。
  2. 消除每个“.”路径名元素(当前目录)。
  3. 消除每个内部的“..”路径名元素(父目录)以及它之前的非“..”元素。
  4. 消除以根路径开始的“..”元素:也就是将路径开头的“/..”替换为“/”。
    返回的路径只有在根目录“/”时才以斜杠结尾。

如果此过程的结果是空字符串,则Clean函数返回字符串“.”。

下面是一个简单的基准测试,将其与正则表达式解决方案进行比较:

package main

import (
	"path"
	"regexp"
	"testing"
)

var p = "///hello//stackover.flow"

func BenchmarkPathRegexp(b *testing.B) {
	re := regexp.MustCompile("/+")
	for i := 0; i < b.N; i++ {
		re.ReplaceAllLiteralString(p, "/")
	}
}

func BenchmarkPathClean(b *testing.B) {
	for i := 0; i < b.N; i++ {
		path.Clean(p)
	}
}

结果:

BenchmarkPathRegexp-4    2000000    794 ns/op
BenchmarkPathClean-4     10000000   145 ns/op
英文:

You can use path.Clean for that.

> func Clean(path string) string

> Clean returns the shortest path name equivalent to path by purely lexical processing. It applies the following rules iteratively until no further processing can be done:

> 1. Replace multiple slashes with a single slash.
> 2. Eliminate each . path name element (the current directory).
> 3. Eliminate each inner .. path name element (the parent directory)
along with the non-.. element that precedes it.
> 4. Eliminate .. elements that begin a rooted path:
that is, replace "/.." by "/" at the beginning of a path.
The returned path ends in a slash only if it is the root "/".

> If the result of this process is an empty string, Clean returns the string ".".

And here's a simple benchmark which compares it with regexp solution:

package main

import (
	&quot;path&quot;
	&quot;regexp&quot;
	&quot;testing&quot;
)

var p = &quot;///hello//stackover.flow&quot;

func BenchmarkPathRegexp(b *testing.B) {
	re := regexp.MustCompile(&quot;/+&quot;)
	for i := 0; i &lt; b.N; i++ {
		re.ReplaceAllLiteralString(p, &quot;/&quot;)
	}
}

func BenchmarkPathClean(b *testing.B) {
	for i := 0; i &lt; b.N; i++ {
		path.Clean(p)
	}
}

Results:

BenchmarkPathRegexp-4   	 2000000	       794 ns/op
BenchmarkPathClean-4    	10000000	       145 ns/op

答案2

得分: 1

只是一个选项。如果你需要替换其他多个字符,你可以使用它。

re, _ := regexp.Compile("/+")

fmt.Println(re.ReplaceAllLiteralString("///hello//stackover.flow", "/"))
英文:

Just an option. You can use it if you need to replace some other multiple characters.

re, _ := regexp.Compile(&quot;/+&quot;)

fmt.Println(re.ReplaceAllLiteralString(&quot;///hello//stackover.flow&quot;, &quot;/&quot;))

huangapple
  • 本文由 发表于 2016年12月27日 16:35:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/41341682.html
匿名

发表评论

匿名网友

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

确定