forked from huichen/sego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.go
136 lines (124 loc) · 3.27 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package sego
import (
"bytes"
"fmt"
)
// 输出分词结果为字符串
//
// 有两种输出模式,以"中华人民共和国"为例
//
// 普通模式(searchMode=false)输出一个分词"中华人民共和国/ns "
// 搜索模式(searchMode=true) 输出普通模式的再细致切分:
// "中华/nz 人民/n 共和/nz 共和国/ns 人民共和国/nt 中华人民共和国/ns "
//
// 搜索模式主要用于给搜索引擎提供尽可能多的关键字,详情请见Token结构体的注释。
func SegmentsToString(segs []Segment, searchMode bool) (output string) {
if searchMode {
for _, seg := range segs {
output += tokenToString(seg.token)
}
} else {
for _, seg := range segs {
output += fmt.Sprintf(
"%s/%s ", textSliceToString(seg.token.text), seg.token.pos)
}
}
return
}
func tokenToString(token *Token) (output string) {
hasOnlyTerminalToken := true
for _, s := range token.segments {
if len(s.token.segments) > 1 {
hasOnlyTerminalToken = false
}
}
if !hasOnlyTerminalToken {
for _, s := range token.segments {
if s != nil {
output += tokenToString(s.token)
}
}
}
output += fmt.Sprintf("%s/%s ", textSliceToString(token.text), token.pos)
return
}
// 输出分词结果到一个字符串slice
//
// 有两种输出模式,以"中华人民共和国"为例
//
// 普通模式(searchMode=false)输出一个分词"[中华人民共和国]"
// 搜索模式(searchMode=true) 输出普通模式的再细致切分:
// "[中华 人民 共和 共和国 人民共和国 中华人民共和国]"
//
// 搜索模式主要用于给搜索引擎提供尽可能多的关键字,详情请见Token结构体的注释。
func SegmentsToSlice(segs []Segment, searchMode bool) (output []string) {
if searchMode {
for _, seg := range segs {
output = append(output, tokenToSlice(seg.token)...)
}
} else {
for _, seg := range segs {
output = append(output, seg.token.Text())
}
}
return
}
func tokenToSlice(token *Token) (output []string) {
hasOnlyTerminalToken := true
for _, s := range token.segments {
if len(s.token.segments) > 1 {
hasOnlyTerminalToken = false
}
}
if !hasOnlyTerminalToken {
for _, s := range token.segments {
output = append(output, tokenToSlice(s.token)...)
}
}
output = append(output, textSliceToString(token.text))
return output
}
// 将多个字元拼接一个字符串输出
func textSliceToString(text []Text) string {
return Join(text)
}
func Join(a []Text) string {
switch len(a) {
case 0:
return ""
case 1:
return string(a[0])
case 2:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return string(a[0]) + string(a[1])
case 3:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return string(a[0]) + string(a[1]) + string(a[2])
}
n := 0
for i := 0; i < len(a); i++ {
n += len(a[i])
}
b := make([]byte, n)
bp := copy(b, a[0])
for _, s := range a[1:] {
bp += copy(b[bp:], s)
}
return string(b)
}
// 返回多个字元的字节总长度
func textSliceByteLength(text []Text) (length int) {
for _, word := range text {
length += len(word)
}
return
}
func textSliceToBytes(text []Text) []byte {
var buf bytes.Buffer
for _, word := range text {
buf.Write(word)
}
return buf.Bytes()
}