89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
package util
|
||
|
||
import (
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
// Flag detection rules: [regex, emoji].
|
||
// Per review-resolution #16: Go RE2 supports \p{Regional_Indicator} and \uFE0F.
|
||
var flagRules []flagRule
|
||
|
||
type flagRule struct {
|
||
re *regexp.Regexp
|
||
emoji string
|
||
}
|
||
|
||
func init() {
|
||
rules := []struct {
|
||
pattern string
|
||
emoji string
|
||
}{
|
||
{`香港|港|hong\s*kong|\bhk\b`, "🇭🇰"},
|
||
{`台湾|台灣|taiwan|\btw\b`, "🇹🇼"},
|
||
{`新加坡|狮城|獅城|singapore|\bsg\b`, "🇸🇬"},
|
||
{`日本|东京|東京|大阪|japan|tokyo|osaka|\bjp\b`, "🇯🇵"},
|
||
{`美国|美國|洛杉矶|洛杉磯|纽约|紐約|united\s*states|los\s*angeles|new\s*york|\bus\b|\busa\b`, "🇺🇸"},
|
||
{`英国|英國|伦敦|倫敦|united\s*kingdom|london|\buk\b`, "🇬🇧"},
|
||
{`德国|德國|法兰克福|法蘭克福|germany|frankfurt|\bde\b`, "🇩🇪"},
|
||
{`韩国|韓國|首尔|首爾|korea|seoul|\bkr\b`, "🇰🇷"},
|
||
}
|
||
for _, r := range rules {
|
||
re, err := regexp.Compile("(?i)" + r.pattern)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
flagRules = append(flagRules, flagRule{re: re, emoji: r.emoji})
|
||
}
|
||
}
|
||
|
||
// DetectFlag returns the flag emoji for a name, or 🏳️ if no match.
|
||
func DetectFlag(name string) string {
|
||
text := strings.ToLower(name)
|
||
for _, rule := range flagRules {
|
||
if rule.re.MatchString(text) {
|
||
return rule.emoji
|
||
}
|
||
}
|
||
return "🏳️"
|
||
}
|
||
|
||
// removeFlagRe matches leading flag emoji sequences and whitespace.
|
||
// Regional Indicator letters are U+1F1E6–U+1F1FF; ZWJ is U+200D; VS16 is U+FE0F.
|
||
var removeFlagRe = regexp.MustCompile(`^[\x{1F1E6}-\x{1F1FF}\x{FE0F}\x{200D}\s]+`)
|
||
|
||
// RemoveFlag strips leading flag emoji and whitespace from a name.
|
||
// Per review-resolution #16: handles ZWJ (\u200D) and variation selector (\uFE0F).
|
||
func RemoveFlag(name string) string {
|
||
cleaned := removeFlagRe.ReplaceAllString(name, "")
|
||
// Also strip leading 🏳️
|
||
cleaned = strings.TrimLeft(cleaned, "🏳️ ")
|
||
return strings.TrimSpace(cleaned)
|
||
}
|
||
|
||
// NormalizeTaiwanFlag maps the Taiwan flag to different flags based on `tw` mode.
|
||
// Per review-resolution #19: three modes — ws/tw/default.
|
||
func NormalizeTaiwanFlag(flag, mode string) string {
|
||
if flag != "🇹🇼" {
|
||
return flag
|
||
}
|
||
switch mode {
|
||
case "ws":
|
||
return "🇼🇸"
|
||
case "tw":
|
||
return "🇹🇼"
|
||
default:
|
||
return "🇨🇳"
|
||
}
|
||
}
|
||
|
||
// IsASCII checks if a string contains only ASCII characters.
|
||
func IsASCII(s string) bool {
|
||
for i := 0; i < len(s); i++ {
|
||
if s[i] > 127 {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|