2 回答

TA貢獻1817條經驗 獲得超14個贊
雖然使用 regexp 通常會產生一個優雅而緊湊的解決方案,但它通常不是最快的。
對于必須用其他子字符串替換某些子字符串的任務,標準庫以以下形式提供了一個非常有效的解決方案strings.Replacer
:
Replacer 用替換項替換字符串列表。多個 goroutines 并發使用是安全的。
您可以使用創建可重復使用的替換器strings.NewReplacer()
,其中列出包含可替換部件及其替換件的對。當你想執行替換時,你只需調用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 答案中的正則表達式解決方案:
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")
}
實施實際上相當快。這是一個簡單的基準測試,將其與上述預編譯的正則表達式解決方案進行比較:
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)
? ? }
}
基準測試結果:
BenchmarkReplacer-4? ? ? 3000000? ? ? ? ? ? ? ?495 ns/op
BenchmarkRegexp-4? ? ? ? ?500000? ? ? ? ? ? ? 2787 ns/op
對于我們的測試輸入,速度提高了5 倍strings.Replacer
以上。
還有另一個優點。在上面的示例中,我們將結果作為新string
值獲取(在兩種解決方案中)。這需要一個新的string
分配。如果我們需要將結果寫入一個io.Writer
(例如,我們正在創建一個 HTTP 響應或將結果寫入一個文件),我們可以避免必須創建新的,string
因為strings.Replacer
它有一個方便的Replacer.WriteString()
方法,它接受一個io.Writer
并寫入result into 它而不分配并將其作為 a 返回string
。與正則表達式解決方案相比,這進一步顯著提高了性能增益。

TA貢獻1866條經驗 獲得超5個贊
您可以將模式“解碼”\R為
U+000DU+000A|[U+000AU+000BU+000CU+000DU+0085U+2028U+2029]
請參閱解釋速記的Java 正則表達式文檔\R:
Linebreak matcher
\R Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
在 Go 中,您可以使用以下內容:
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支持的正則表達式轉義序列替換:
re := regexp.MustCompile(`\r\n|[\r\n\v\f\x{0085}\x{2028}\x{2029}]`)
- 2 回答
- 0 關注
- 397 瀏覽
添加回答
舉報