golang 字符串技巧分享(1)--分割

2019-10-10 09:27:30 +08:00
 guonaihong

开发过程中少不了要于字符串打交道。假如要对一个文本串进行分段,分割符是.?;. 还要保留分割符号,就不能使用常用的 string.Split 函数,Split 会把分割符去除。下面介绍两种方式。

基于状态方法

用时 2:42

package main

import (
    "fmt"
)

func main() {
    const input = "1,2,3,4,5;6.7?"
    var all []string

    prev := 0
    for i := 0; i < len(input); i++ {
        switch input[i] {
        case ',', '.', ';', '?':
            all = append(all, input[prev:i+1])
            prev = i + 1 
        }
    }   

    for _, v := range all {
        fmt.Printf("%s\n", v)
    }   
}

基于 scanner

用时 1:28(复制官网例子,修改回调函数的内容,所以用时很短)

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    // Comma-separated list; last entry is empty.
    const input = "1,2,3,4,5;6.7?"
    scanner := bufio.NewScanner(strings.NewReader(input))
    // Define a split function that separates on commas.
    onComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
        for i := 0; i < len(data); i++ {
            switch data[i] {
            case ',', '.', ';', '?':
                return i + 1, data[:i+1], nil 
            }   
        }
        if !atEOF {
            return 0, nil, nil 
        }   
        // There is one final token to be delivered, which may be the empty string.
        // Returning bufio.ErrFinalToken here tells Scan there are no more tokens after this
        // but does not trigger an error to be returned from Scan itself.
        return 0, data, bufio.ErrFinalToken
    }   
    scanner.Split(onComma)
    // Scan.
    for scanner.Scan() {
        fmt.Printf("%q ", scanner.Text())
    }   
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading input:", err)
    }   
}

交流学习

上面两种方式都把编码时间写上,欢迎 v 贴出自己的方法,互相学习。

github

https://github.com/guonaihong/gout

2619 次点击
所在节点    程序员
9 条回复
io123
2019-10-10 09:46:00 +08:00
果然还是 Py 大法好
claysec
2019-10-10 10:34:30 +08:00
@io123 +1 突然看着 go 的语法好迷啊。。
T3RRY
2019-10-10 14:08:03 +08:00
+1
zhuzeitou
2019-10-10 14:37:15 +08:00
第一段代码没处理遍历结束后剩余的最后一段内容……
Biwood
2019-10-10 15:05:59 +08:00
package main

import (
"fmt"
"regexp"
"strings"
)

func main() {
const input = "1,2,3,4,5;6.7?"
re := regexp.MustCompile(`([,;\.\?])`)
newStr := re.ReplaceAllString(input, "$1-")
fmt.Printf("%q\n", strings.Split(newStr, "-"))
}

go 的正则没有后行断言,否则更简洁一些
guonaihong
2019-10-10 18:24:27 +08:00
@zhuzeitou 是的。马上改下。
guonaihong
2019-10-10 18:34:18 +08:00
@Biwood 这思路挺好。可以把-分割符换成不可见字符\x000(数字 0)
reus
2019-10-10 18:48:34 +08:00
guonaihong
2019-10-10 21:07:07 +08:00
@reus 可以可以。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/607713

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX