2 回答

TA貢獻(xiàn)1817條經(jīng)驗(yàn) 獲得超14個贊
雖然使用 regexp 通常會產(chǎn)生一個優(yōu)雅而緊湊的解決方案,但它通常不是最快的。
對于必須用其他子字符串替換某些子字符串的任務(wù),標(biāo)準(zhǔn)庫以以下形式提供了一個非常有效的解決方案strings.Replacer
:
Replacer 用替換項(xiàng)替換字符串列表。多個 goroutines 并發(fā)使用是安全的。
您可以使用創(chuàng)建可重復(fù)使用的替換器strings.NewReplacer()
,其中列出包含可替換部件及其替換件的對。當(dāng)你想執(zhí)行替換時,你只需調(diào)用Replacer.Replace()
.
它看起來像這樣:
const replacement = "<br>\n"
var replacer = strings.NewReplacer(
? ? "\r\n", replacement,
? ? "\r", replacement,
? ? "\n", replacement,
? ? "\v", replacement,
? ? "\f", replacement,
? ? "\u0085", replacement,
? ? "\u2028", replacement,
? ? "\u2029", replacement,
)
func replaceReplacer(s string) string {
? ? return replacer.Replace(s)
}
以下是Wiktor 答案中的正則表達(dá)式解決方案:
var re = regexp.MustCompile(`\r\n|[\r\n\v\f\x{0085}\x{2028}\x{2029}]`)
func replaceRegexp(s string) string {
? ? return re.ReplaceAllString(s, "<br>\n")
}
實(shí)施實(shí)際上相當(dāng)快。這是一個簡單的基準(zhǔn)測試,將其與上述預(yù)編譯的正則表達(dá)式解決方案進(jìn)行比較:
const input = "1st\nsecond\r\nthird\r4th\u0085fifth\u2028sixth"
func BenchmarkReplacer(b *testing.B) {
? ? for i := 0; i < b.N; i++ {
? ? ? ? replaceReplacer(input)
? ? }
}
func BenchmarkRegexp(b *testing.B) {
? ? for i := 0; i < b.N; i++ {
? ? ? ? replaceRegexp(input)
? ? }
}
基準(zhǔn)測試結(jié)果:
BenchmarkReplacer-4? ? ? 3000000? ? ? ? ? ? ? ?495 ns/op
BenchmarkRegexp-4? ? ? ? ?500000? ? ? ? ? ? ? 2787 ns/op
對于我們的測試輸入,速度提高了5 倍strings.Replacer
以上。
還有另一個優(yōu)點(diǎn)。在上面的示例中,我們將結(jié)果作為新string
值獲?。ㄔ趦煞N解決方案中)。這需要一個新的string
分配。如果我們需要將結(jié)果寫入一個io.Writer
(例如,我們正在創(chuàng)建一個 HTTP 響應(yīng)或?qū)⒔Y(jié)果寫入一個文件),我們可以避免必須創(chuàng)建新的,string
因?yàn)?code>strings.Replacer它有一個方便的Replacer.WriteString()
方法,它接受一個io.Writer
并寫入result into 它而不分配并將其作為 a 返回string
。與正則表達(dá)式解決方案相比,這進(jìn)一步顯著提高了性能增益。

TA貢獻(xiàn)1866條經(jīng)驗(yàn) 獲得超5個贊
您可以將模式“解碼”\R為
U+000DU+000A|[U+000AU+000BU+000CU+000DU+0085U+2028U+2029]
請參閱解釋速記的Java 正則表達(dá)式文檔\R:
Linebreak matcher
\R Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
在 Go 中,您可以使用以下內(nèi)容:
func removeLBR(text string) string {
re := regexp.MustCompile(`\x{000D}\x{000A}|[\x{000A}\x{000B}\x{000C}\x{000D}\x{0085}\x{2028}\x{2029}]`)
return re.ReplaceAllString(text, ``)
}
這是一個Go 演示。
一些 Unicode 代碼可以用Go regexp支持的正則表達(dá)式轉(zhuǎn)義序列替換:
re := regexp.MustCompile(`\r\n|[\r\n\v\f\x{0085}\x{2028}\x{2029}]`)
- 2 回答
- 0 關(guān)注
- 414 瀏覽
添加回答
舉報(bào)