いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-223 (bufio.Scanner で カスタムな bufio.SplitFunc を利用するやり方)

概要

使うことはほぼ無いかもしれませんが、知ってるとちょっと便利かもしれません。

bufio.Scanner さん に対して、独自のデリミタでSplitしてほしい場合、bufio.SplitFunc を作って渡します。

このやり方がちょっと難しかったので、自分用に以下にメモメモ。。。

サンプル

package scannerop

import (
    "bufio"
    "bytes"
    "fmt"
    "strings"

    "github.com/devlights/gomy/output"
)

// Custom -- bufio.Scanner に 独自の bufio.SplitFunc を指定して処理するサンプルです.
//
// REFERENCES
//   - https://pkg.go.dev/bufio@go1.18.1#Scanner
//   - https://pkg.go.dev/bufio@go1.18.1#SplitFunc
func Custom() error {
    var (
        gen = func(delimiter []byte) bufio.SplitFunc {
            return func(data []byte, atEOF bool) (advance int, token []byte, err error) {
                if atEOF && len(data) == 0 {
                    // 処理するべきデータがない
                    return 0, nil, nil
                }

                if i := bytes.Index(data, delimiter); i >= 0 {
                    // 見つかったので、Scanner 側にトークンを渡す
                    return i + len(delimiter), data[0:i], nil
                }

                if atEOF {
                    // 最後のデータを纏めて Scanner 側に渡す
                    return len(data), data, nil
                }

                // このターンではトークンが見つからなかったので、更に読み進むように Scanner に通知
                return 0, nil, nil
            }
        }
    )

    for i, fn := range []bufio.SplitFunc{bufio.ScanWords, gen([]byte("[TAB]")), gen([]byte("{TAB}"))} {
        var (
            r = strings.NewReader("hello[TAB]world[TAB]こんにちわ{TAB}世界")
            s = bufio.NewScanner(r)
        )

        s.Split(fn)

        for s.Scan() {
            prefix := fmt.Sprintf("[%d]", i)
            output.Stdoutl(prefix, s.Text())
        }
    }

    return nil
}

実行すると以下のようになります。

gitpod /workspace/try-golang (master) $ task run
task: [run] go run . -onetime

ENTER EXAMPLE NAME: scannerop_custom

[Name] "scannerop_custom"
[0]                  hello[TAB]world[TAB]こんにちわ{TAB}世界
[1]                  hello
[1]                  world
[1]                  こんにちわ{TAB}世界
[2]                  hello[TAB]world[TAB]こんにちわ
[2]                  世界


[Elapsed] 83.009µs

参考情報


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。