118 lines
2.4 KiB
Go
118 lines
2.4 KiB
Go
package util
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
// 占位符替换 xxx{placeholder}xxx
|
||
func ReplacePlaceholder(str string, placeholder string, value string) string {
|
||
return strings.ReplaceAll(str, "{"+placeholder+"}", value)
|
||
}
|
||
|
||
// 构建跳转a标签,新tab打开
|
||
func BuildJumpLink(url string, text string) string {
|
||
return "<a href=\"" + url + "\" target=\"_blank\">" + text + "</a>"
|
||
}
|
||
|
||
func EscapeJSONString(s string) string {
|
||
b, _ := json.Marshal(s)
|
||
return string(b[1 : len(b)-1])
|
||
}
|
||
|
||
// string 转 int
|
||
func StringToInt(s string) int {
|
||
i, _ := strconv.Atoi(s)
|
||
return i
|
||
}
|
||
|
||
// string 转 float64
|
||
func StringToFloat64(s string) float64 {
|
||
i, _ := strconv.ParseFloat(s, 64)
|
||
return i
|
||
}
|
||
|
||
// 是否包含在数组中
|
||
func Contains[T comparable](strings []T, str T) bool {
|
||
for _, s := range strings {
|
||
if s == str {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// json LLM专用字符串修复
|
||
func JSONRepair(input string) (string, error) {
|
||
s := strings.TrimSpace(input)
|
||
|
||
s = trimToJSONObject(s)
|
||
s = normalizeQuotes(s)
|
||
s = removeTrailingCommas(s)
|
||
s = quoteObjectKeys(s)
|
||
s = balanceBrackets(s)
|
||
|
||
// 最终校验
|
||
var js any
|
||
if err := json.Unmarshal([]byte(s), &js); err != nil {
|
||
return "", fmt.Errorf("json repair failed: %w", err)
|
||
}
|
||
return s, nil
|
||
}
|
||
|
||
// 裁剪前后垃圾文本
|
||
func trimToJSONObject(s string) string {
|
||
start := strings.IndexAny(s, "{[")
|
||
end := strings.LastIndexAny(s, "}]")
|
||
if start == -1 || end == -1 || start >= end {
|
||
return s
|
||
}
|
||
return s[start : end+1]
|
||
}
|
||
|
||
// 引号统一
|
||
func normalizeQuotes(s string) string {
|
||
// 只替换“看起来像字符串的单引号”
|
||
re := regexp.MustCompile(`'([^']*)'`)
|
||
return re.ReplaceAllString(s, `"$1"`)
|
||
}
|
||
|
||
// 删除尾随逗号
|
||
func removeTrailingCommas(s string) string {
|
||
re := regexp.MustCompile(`,(\s*[}\]])`)
|
||
return re.ReplaceAllString(s, `$1`)
|
||
}
|
||
|
||
// 给 object key 自动补双引号
|
||
func quoteObjectKeys(s string) string {
|
||
re := regexp.MustCompile(`([{,]\s*)([a-zA-Z0-9_]+)\s*:`)
|
||
return re.ReplaceAllString(s, `$1"$2":`)
|
||
}
|
||
|
||
// 括号补齐
|
||
func balanceBrackets(s string) string {
|
||
var stack []rune
|
||
for _, r := range s {
|
||
switch r {
|
||
case '{', '[':
|
||
stack = append(stack, r)
|
||
case '}', ']':
|
||
if len(stack) > 0 {
|
||
stack = stack[:len(stack)-1]
|
||
}
|
||
}
|
||
}
|
||
for i := len(stack) - 1; i >= 0; i-- {
|
||
switch stack[i] {
|
||
case '{':
|
||
s += "}"
|
||
case '[':
|
||
s += "]"
|
||
}
|
||
}
|
||
return s
|
||
}
|