package emoji import ( "fmt" "regexp" "strconv" "strings" "unicode/utf16" ) func init() { for i, emoji := range emojiMap { code_points := []string{} for _, v := range strings.Split(emojiMap[i].CodePoint, " ") { switch len(v) { case 4: code_points = append(code_points, v) case 5: code_points = append(code_points, transfer(v)...) default: } } if len(code_points) == 0 { for _, v := range strings.Split(emojiMap[i].CodePoint, "-") { switch len(v) { case 4: code_points = append(code_points, v) case 5: code_points = append(code_points, transfer(v)...) default: } } } if len(code_points) == 0 { delete(emojiMap, i) } else { emoji.CodePoint2 = code_points emojiMap[i] = emoji } } } func ConvertRegex(input string) (string, int) { count := strings.Count(input, "%s") // 定义要转义的字符集合 escapeSet := []string{"\\", "[", "]", "(", ")", "{", "}", ".", "*", "+", "?", "^", "$", "|"} // 定义正则表达式模式和替换字符串 var pattern = `%s` var replaceStr = `([0-9A-Za-z]{4})` // 对可能引起正则表达式冲突的字符进行转义 for _, esc := range escapeSet { input = strings.ReplaceAll(input, esc, "\\"+esc) } // 将子匹配内容替换为指定格式的正则表达式 replaced := strings.ReplaceAll(input, pattern, replaceStr) // 返回转换结果和是否大写的标记 return replaced, count } // \[emoji=[0-9A-Z]{4}\] func ReplaceToEmojis(str string, format string) string { pattern, count := ConvertRegex(format) if count == 1 { str = regexp.MustCompile("[0-9]"+pattern+pattern).ReplaceAllStringFunc(str, func(s string) string { if !strings.EqualFold(strings.ToUpper(s[1:]), strings.ToUpper(fmt.Sprintf(format+format, "FE0F", "20E3"))) { //"[emoji=FE0F][emoji=20E3]" return s } return fmt.Sprintf(format, fmt.Sprintf("%04X", s[0])) + s[1:] }) } else if count == 2 { str = regexp.MustCompile("[0-9]"+pattern).ReplaceAllStringFunc(str, func(s string) string { if !strings.EqualFold(strings.ToUpper(s[1:]), strings.ToUpper(fmt.Sprintf(format, "FE0F", "20E3"))) { //"[emoji=FE0F][emoji=20E3]" return s } return fmt.Sprintf(format, fmt.Sprintf("%04X", s[0]), "0000") + s[1:] }) } else { return str } res := str h := func(ssr *[]string) string { for i := range *ssr { if (*ssr)[i] == "0000" { s := append((*ssr)[:i], (*ssr)[i+1:]...) ssr = &s } } chs := []string{} ch := "" l := 100 lft := []string{} again: for j := range emojiMap { ok, left := matchPrefix(emojiMap[j].CodePoint2, *ssr) if ok { if ln := len(left); ln < l { ch = emojiMap[j].Character l = ln lft = left } } } if ch != "" { chs = append(chs, ch) if len(lft) != 0 { ch = "" l = 100 *ssr = lft lft = []string{} goto again } } else { for _, hex := range *ssr { r, err := HexToRune(hex) if err == nil { chs = append(chs, string([]rune{r})) } } } return strings.Join(chs, "") } sss := regexp.MustCompile(pattern).FindAllStringSubmatchIndex(str, -1) ssr := []string{} ssrs := []string{} e := -1 for i := range sss { ss := sss[i] a, b := ss[0], ss[1] //, ss[2], ss[3] // fmt.Println(str[a:b], str[c:d]) //结算 if e != a && len(ssr) != 0 { rs := h(&ssr) res = strings.Replace(res, strings.Join(ssrs, ""), rs, 1) ssr = []string{} ssrs = []string{} e = -1 } ssrs = append(ssrs, str[a:b]) k := []int{} for _, j := range ss[2:] { k = append(k, j) if len(k) == 2 { ssr = append(ssr, strings.ToUpper(str[k[0]:k[1]])) k = []int{} } } // ssr = append(ssr, strings.ToUpper(str[c:d])) e = b } if len(ssr) != 0 { rs := h(&ssr) res = strings.Replace(res, strings.Join(ssrs, ""), rs, 1) e = -1 } return res } func transfer(str string) []string { // 将输入字符串解析为十六进制数 unicodeValue, err := strconv.ParseUint(str, 16, 32) if err != nil { panic(err) } // 将 Unicode 编码值转换为 UTF-16 编码单元 utf16Units := utf16.Encode([]rune{rune(unicodeValue)}) // 将 UTF-16 编码单元格式化为字符串,并返回字符串切片 return []string{fmt.Sprintf("%04X", utf16Units[0]), fmt.Sprintf("%04X", utf16Units[1])} } func matchPrefix(s1 []string, s2 []string) (bool, []string) { if len(s1) > len(s2) { return false, s2 } for i := range s1 { if s1[i] != s2[i] { return false, nil } } return true, s2[len(s1):] } func RuneToHx(a rune) string { return fmt.Sprintf("%04X", a) } func HexToRune(hexStr string) (rune, error) { // 解析十六进制字符串,获取对应的无符号整数 u, err := strconv.ParseUint(hexStr, 16, 32) if err != nil { return 0, err } // 将无符号整数转换为 rune 类型的 Unicode 编码值 r := rune(u) // 返回转换结果 return r, nil }