Golang的中文分詞開發包:cut

jopen 9年前發布 | 16K 次閱讀 cut Google Go/Golang開發

cut

Golang寫的中文分詞開發包。

參考

sego

兩個重要方法

// Dictionary結構體實現了一個字串前綴樹,
// 一個分詞可能出現在葉子節點也有可能出現在非葉節點
type Dictionary struct {
    root           node     // 根節點
    maxTokenLength int      // 詞典中最長的分詞
    numTokens      int      // 詞典中分詞數目
    tokens         []*Token // 詞典中所有的分詞,方便遍歷
    totalFrequency int64    // 詞典中所有分詞的頻率之和
}

// 前綴樹節點
type node struct {
    word     Text    // 該節點對應的字元
    token    *Token  // 當此節點沒有對應的分詞時值為nil
    children []*node // 該字元后繼的所有可能字元,當為葉子節點時為空
}

//分詞器結構體
type Segmenter struct {
    dict *Dictionary
}

// 字典加載方法
// 可以載入多個詞典文件,文件名用","分隔,排在前面的詞典優先載入分詞,比如
//  "用戶詞典.txt,通用詞典.txt"
// 當一個分詞既出現在用戶詞典也出現在通用詞典中,則優先使用用戶詞典。
// 詞典的格式為(每個分詞一行):
//  分詞文本 頻率 詞性
func (self * Segmenter) LoadDictionary(files string)

// 對文本分詞
// 輸入參數:
//  bytes   UTF8文本的字節數組
// 輸出:
//  []Segment   劃分的分詞
func (self *Segmenter) Go(bytes []byte, model bool) []Segment

/*
cut 分詞服務器提供JSON格式的RPC服務
datatime: 2015-10-12
author: aosen
homepage: https://github.com/aosen/
url:
    "/"
輸入:
    GET模式輸入text參數
輸出:
    {
        result:[
            {"text":"服務器", "pos":"n"},
            {"text":"指令", "pos":"n"},
            ...
        ],
        err: 0,
        errmsg: ""
    }
*/
package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "github.com/aosen/cut"
    "io"
    "log"
    "net/http"
    "strings"
)

var (
    host = flag.String("host", "127.0.0.1", "HTTP服務器主機名")
    port = flag.Int("port", 2019, "HTTP服務器端口")
    dict = flag.String("dict", "dict.txt", "詞典文件")
    //生成分詞器對象
    segmenter = cut.Segmenter{}
)

/*返回的JSON數據*/
type Response struct {
    Values []*Value `json:"result"`
    Err    int      `json:"err"`
    Errmsg string   `json:"errmsg"`
}

type Value struct {
    Text string `json:"text"`
    Pos  string `json:"pos"`
}

var ERR = map[int]string{
    0:   "success",
    500: "Invalid argument",
}

func JsonRpcServer(w http.ResponseWriter, req *http.Request) {
    //結果處理
    JsonResponse := func(v []*Value, code int) {
        resp, _ := json.Marshal(&Response{
            Values: v,
            Err:    code,
            Errmsg: ERR[code],
        })
        //w.Header().Set("Content-Type", "application/json")
        io.WriteString(w, string(resp))
    }
    //通用處理方法
    handle := func(text string, mode string) {
        if text == "" || (!strings.EqualFold(mode, "1") && !strings.EqualFold(mode, "0")) {
            JsonResponse(nil, 500)
        } else {
            //整理為輸出格式
            s := []*Value{}
            //開始分詞
            func() {
                for _, seg := range segmenter.Go([]byte(text),
                    func() bool {
                        if mode == "1" {
                            return true
                        } else {
                            return false
                        }
                    }()) {
                    s = append(s, &Value{
                        Text: seg.Token().Text(),
                        Pos:  seg.Token().Pos(),
                    })
                }
            }()
            JsonResponse(s, 0)
        }
    }
    // 得到要分詞的文本
    if req.Method == "GET" {
        text := req.URL.Query().Get("text")
        mode := req.URL.Query().Get("mode")
        handle(text, mode)
    } else if req.Method == "POST" {
        text := req.PostFormValue("text")
        mode := req.PostFormValue("mode")
        handle(text, mode)
    }
}

func main() {
    flag.Parse()
    //初始化分詞器
    segmenter.LoadDictionary(*dict)
    http.HandleFunc("/", JsonRpcServer)
    log.Printf("cut server run on %s:%d", *host, *port)
    http.ListenAndServe(fmt.Sprintf("%s:%d", *host, *port), nil)
}

項目主頁:http://www.baiduhome.net/lib/view/home/1445650626163

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!