是否可以在Golang中的一次操作中提取字符串的一部分并替换这些部分?

说我想从字符串中提取所有数字(最有可能使用正则表达式匹配),我也想替换那些数字 数字与通用占位符(如“#”)匹配。</ p>

使用FindAll,然后使用ReplaceAll,很容易分为两部分。 但是,我对执行此类操作的性能成本有严重的怀疑。</ p>

因此,请使用字符串</ p>

 “ sdasd 3.2%sadas 6。  .. +8.9“ 
</ code> </ pre>

替换为</ p>

 ” sdasd#%sadas#... +#  “ 
</ code> </ pre>

并获得一个切片</ p>

  [3.2,6.0,8.9] 
</ code> < / pre>

以尽可能高性能的方式。</ p>

编辑:我实现了regexp.FindAllString + regexp.ReplaceAllString,对我的应用程序造成的性能影响很小 。 希望我会尝试Elliot Chance的方法,并在有时间的时候将两者进行比较。</ p>
</ div>

展开原文

原文

Say I want to extract all numbers from a string (Most likely using regex matching) and I also want to replace those number matches with a generic placeholder like "#".

This is easily done in two parts using FindAll, then ReplaceAll. However I have serious doubts about the performance costs of doing such operations.

So take a string

"sdasd 3.2% sadas 6 ... +8.9"

replace it with

"sdasd #% sadas # ... +#"

and get a slice

[3.2,6.0,8.9]

In the most performant way possible.

Edit : I implemented the regexp.FindAllString + regexp.ReplaceAllString and the performance hit to my app was very minimal. I will hopefully try Elliot Chance's approach and compare the two when I have time.

duangu1033
duangu1033 我认为有些人已经找到了一种方法可以做到这一点elliot.silvrback.com/…
大约 3 年之前 回复
douzhuiqiu4923
douzhuiqiu4923 我完全同意行数与性能无关。我只是假设拥有这两个regex调用会在每个字符串中循环两次,并且正在询问是否可以在一次迭代中完成,因为我认为这样做会提高性能。
大约 3 年之前 回复
dongyou8368
dongyou8368 我同意@Kaedys的观点,但是对于字符串处理而言,正则表达式通常很方便,但通常会造成可怕的过大杀伤力,尤其是在性能是最主要的问题上。但是,是的,性能和LOC通常是完全不相关的。
大约 3 年之前 回复
dqh1984
dqh1984 它需要两个函数调用的事实并不一定意味着它的性能很差。行数!=性能。在这种情况下,这样的功能仍然必须同时执行,找到每个项目然后将其替换。但是,如果您确实希望它是一行,则可以将这些值提取到转到golang.org/pkg/regexp/#Regexp.ReplaceAllFunc的附件中。可以肯定的是,这样做实际上会降低效率。
大约 3 年之前 回复

2个回答



如果您需要原始性能,则regexp很少会实现它,即使它很方便。 逐个令牌地迭代令牌应该很快。 某些代码:</ p>

  input:=“ sdasd 3.2 sadas 6” 
output:= [] string {}
numbers:= [] float64 {}

对于_, tok:=范围字符串。Split(input,“”){
如果f,err:= strconv.ParseFloat(tok,64); err == nil {
数字= append(数字,f)
tok =“#”
}
输出= append(output,tok)
}
finalString:= strings.Join(output,“” )
fmt.Println(finalString,数字)
</ code> </ pre>

操场上的链接 </ p>

我敢肯定,这里还有更多的优化方法,但这是我通常采用的方法。</ p >
</ div>

展开原文

原文

If you need raw performance than regexp is rarely the way to achieve it, even if it is convenient. Iterating token by token should be pretty fast. Some code:

input := "sdasd 3.2 sadas 6"
output := []string{}
numbers := []float64{}

for _, tok := range strings.Split(input, " ") {
    if f, err := strconv.ParseFloat(tok, 64); err == nil {
        numbers = append(numbers, f)
        tok = "#"
    }
    output = append(output, tok)
}
finalString := strings.Join(output, " ")
fmt.Println(finalString, numbers)

playground link

I'm sure there's a few more optimizations in there that could be made, but this is the general approach I'd take.

duanhuang2804
duanhuang2804 如果在解析为浮点数之前检查最后一个字节以查看是否将其%然后删除它(与第一个字节为'+'相同),它可能仍然可以工作。 我认为'-'应该已经正确解析了。 不幸的是,strings.Split返回一个字符串标记,所以我必须将其解析为[] byte ...
大约 3 年之前 回复
doulu1968
doulu1968 我懂了。 尽管如此,每当我觉得正则表达式可以解决我的问题时,我都一定要问一个简单的for循环是否也可以解决它。
大约 3 年之前 回复
dongshui2254
dongshui2254 可悲的是,在对我的数据进行测试之后,分割成“”并不能涵盖所有内容……某些数字上附加了“%”,“ +”或“-”。 对不起,我的问题不清楚。 这是我首先研究正则表达式的主要原因。
大约 3 年之前 回复
duanhuan3012
duanhuan3012 如有疑问,请运行基准测试。 我敢打赌,这很容易击败regexp,但过去的事情也让我感到惊讶。
大约 3 年之前 回复
dqz13288
dqz13288 golang.org/src/strconv/atof.go?s=11079:11134#L477实际上有点通读。
大约 3 年之前 回复
douju4278
douju4278 是的,这是一个问题。 但是,如果不是看起来像数字的东西,ParseFloat将会非常快。 只要看足够多的字符就知道它不是数字,然后返回。
大约 3 年之前 回复
dongnan4571
dongnan4571 这听起来优雅而简单,说实话,我并不希望在每个单词上都调用ParseFloat会表现出色,但是我会尝试一下。 我以为只要预先对模式进行预编译就可以使正则表达式匹配有效,但是似乎我错了。
大约 3 年之前 回复



永远不要低估正则表达式的功能,尤其是Go的RE2引擎。</ p>

,如果没有基准测试,就可以假设任何有关性能的信息。 总是令人惊讶。</ p>

正则表达式通常是编译和缓存的。 可以肯定的是,您可以先编译它来进行优化。</ p>
</ div>

展开原文

原文

Never underestimate the power of regex, especially the RE2 engine of Go.

Also, never, ever, assume anything about performance without benchmarking. It always surprises.

The regular expression is usually compiled and cached. To be sure, you could optimize by compiling it first.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问