1 回答

TA貢獻1810條經驗 獲得超5個贊
使用正則表達式通常比手動執行要慢。由于任務并不復雜,因此非正則表達式解決方案也不復雜。
您可以使用strings.FieldsFunc()
在一組字符上拆分字符串,并strings.TrimSpace()
去除前導和尾隨空格。
這是一個簡單的函數,可以執行您想要的操作:
func split(s, sep string) (tokens []string) {
? ? fields := strings.FieldsFunc(s, func(r rune) bool {
? ? ? ? return strings.IndexRune(sep, r) != -1
? ? })
? ? for _, s2 := range fields {
? ? ? ? s2 = strings.TrimSpace(s2)
? ? ? ? if s2 != "" {
? ? ? ? ? ? tokens = append(tokens, s2)
? ? ? ? }
? ? }
? ? return
}
測試它:
fmt.Printf("%q\n", split("a,b;c, de; ; fg ", ",;"))
fmt.Printf("%q\n", split("a[b]c[ de/ / fg ", "[]/"))
輸出(在Go Playground上嘗試):
["a" "b" "c" "de" "fg"]
["a" "b" "c" "de" "fg"]
改進
如果性能是一個問題并且你必須split()多次調用這個函數,那么從分隔符創建一個類似集合的映射并重用它會是有利可圖的,所以在傳遞給的函數內部,strings.FieldFunc()你可以簡單地檢查是否rune在這個地圖,所以你不需要打電話來strings.IndexRune()決定給定的是否rune是一個分隔符。
如果您的分隔符很少(例如 1-3 個字符),性能提升可能并不顯著,但如果您有更多分隔符,則使用映射可以顯著提高性能。
這就是它的樣子:
var (
? ? sep1 = map[rune]bool{',': true, ';': true}
? ? sep2 = map[rune]bool{'[': true, ']': true, '/': true}
)
func split(s string, sep map[rune]bool) (tokens []string) {
? ? fields := strings.FieldsFunc(s, func(r rune) bool {
? ? ? ? return sep[r]
? ? })
? ? for _, s2 := range fields {
? ? ? ? s2 = strings.TrimSpace(s2)
? ? ? ? if s2 != "" {
? ? ? ? ? ? tokens = append(tokens, s2)
? ? ? ? }
? ? }
? ? return
}
測試它:
fmt.Printf("%q\n", split("a,b;c, de; ; fg ", sep1))
fmt.Printf("%q\n", split("a[b]c[ de/ / fg ", sep2))
輸出是一樣的。
- 1 回答
- 0 關注
- 131 瀏覽
添加回答
舉報