gpt4 book ai didi

go - 从大文本中删除所有非字母数字字符的有效方法

转载 作者:IT王子 更新时间:2023-10-29 01:51:48 25 4
gpt4 key购买 nike

我需要处理大量文本,其中一个步骤是删除所有非字母数字字符。我正试图找到一种有效的方法来做到这一点。

到目前为止我有两个功能:

func stripMap(str, chr string) string {
return strings.Map(func(r rune) rune {
if strings.IndexRune(chr, r) < 0 {
return r
}
return -1
}, str)
}

在这里我实际上必须提供所有非字母字符的字符串。

和普通的旧正则表达式

func stripRegex(in string) string {
reg, _ := regexp.Compile("[^a-zA-Z0-9 ]+")
return reg.ReplaceAllString(in, "")
}

正则表达式似乎慢得多

BenchmarkStripMap-8        30000         37907 ns/op        8192 B/op          2 allocs/op

BenchmarkStripRegex-8 10000 131449 ns/op 57552 B/op 35 allocs/op

寻求建议。还有其他更好的方法吗?改善以上?

最佳答案

因为幸存的 rune 少于utf8.RuneSelf ,这个问题可以通过对字节进行操作来解决。如果任何字节不在 [^a-zA-Z0-9 ] 中,则该字节是要删除的 rune 的一部分。

func strip(s string) string {
var result strings.Builder
for i := 0; i < len(s); i++ {
b := s[i]
if ('a' <= b && b <= 'z') ||
('A' <= b && b <= 'Z') ||
('0' <= b && b <= '9') ||
b == ' ' {
result.WriteByte(b)
}
}
return result.String()
}

此函数的一个变体是通过调用 result.Grow 来预分配结果:

func strip(s string) string {
var result strings.Builder
result.Grow(len(s))
...

这确保函数进行一次内存分配,但如果幸存 rune 与源 rune 的比率很低,则内存分配可能会比需要的大得多。

此答案中的 strip 函数被编写为与 string 参数和结果类型一起使用,因为这些是问题中使用的类型。

如果应用程序正在处理 []byte 源文本并且可以修改该源文本,那么就地更新 []byte 会更有效.为此,将幸存的字节复制到 slice 的开头并在完成后重新 slice 。这避免了 strings.Builder 中的内存分配和开销。这种变化类似于 peterSO 对这个问题的回答。

func strip(s []byte) []byte {
n := 0
for _, b := range s {
if ('a' <= b && b <= 'z') ||
('A' <= b && b <= 'Z') ||
('0' <= b && b <= '9') ||
b == ' ' {
s[n] = b
n++
}
}
return s[:n]
}

根据使用的实际数据,此答案中的一种方法可能比问题中的方法更快。

关于go - 从大文本中删除所有非字母数字字符的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54461423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com