Golang中Unicode "Is"函数 - 哪个最值得使用?
Golang中Unicode "Is"函数 - 哪个最值得使用? 我明白这可能有些主观,所以我会尽量概述我比较确定的部分,以尽可能缩小关注范围。
我想进行一些基本的登录名检查。我的目标是允许所有可能在姓名中使用的Unicode字符,包括非英语语言中的字符,以及数字和可能在姓名中出现的基本标点符号,但不包括像 !, ? 这样的书写标点符号,也不包括像CR、LF等控制字符,不过在这种情况下允许使用空格。
显然应该允许的是:unicode.IsDigit/unicode.IsNumber、unicode.IsLetter,并且不使用 IsControl。但我对 IsMark 不太清楚,因为它看起来有些子类别可能有用,有些则不然。另外,我对 IsGraphic 没有概念,对 IsPunct 也不确定。
有没有人深入研究过Unicode,对于允许哪些Unicode字符是合理的选择有什么想法吗?
更新: 在尝试了来自不同国家的词语后,我目前得出了以下方案:
switch {
case unicode.IsDigit(chr), unicode.IsLetter(chr), unicode.IsSpace(chr), unicode.Is(unicode.Dash, chr), unicode.Is(unicode.Hyphen, chr):
case unicode.IsPunct(chr):
if !strings.ContainsAny(string(chr),"’'ʼ՚ߴߵߵ’'") { // 撇号
logger.Error(`Message`)
}
default :
logger.Error(`Message`)
}
更多关于Golang中Unicode "Is"函数 - 哪个最值得使用?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang中Unicode "Is"函数 - 哪个最值得使用?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go的unicode包中,IsGraphic和IsPrint函数对于登录名验证可能是最合适的选择。IsGraphic涵盖了所有图形字符(字母、数字、标点、符号、空白),而IsPrint在此基础上排除了控制字符。对于你的用例,我建议使用IsGraphic并排除特定标点。
以下是更清晰的实现示例:
func isValidLoginNameChar(chr rune) bool {
// 首先检查基本允许的类别
if unicode.IsDigit(chr) || unicode.IsLetter(chr) || unicode.IsSpace(chr) {
return true
}
// 允许特定标点
if chr == '-' || chr == '_' || chr == '.' || chr == '\'' {
return true
}
// 使用IsGraphic检查其他图形字符,但排除不需要的标点
if unicode.IsGraphic(chr) {
// 排除特定标点符号
switch chr {
case '!', '?', '@', '#', '$', '%', '^', '&', '*', '(', ')',
'=', '+', '[', ']', '{', '}', '|', '\\', ';', ':', '"',
'<', '>', '/', '~', '`':
return false
default:
// 检查是否为控制字符(虽然IsGraphic通常已排除)
if unicode.IsControl(chr) {
return false
}
return true
}
}
return false
}
// 完整验证函数
func ValidateLoginName(name string) bool {
for _, chr := range name {
if !isValidLoginNameChar(chr) {
return false
}
}
return true
}
或者使用更简洁的IsPrint方案:
func isValidLoginNameChar(chr rune) bool {
// 允许的标点白名单
allowedPunct := map[rune]bool{
'-': true, '_': true, '.': true, '\'': true,
'ʼ': true, '՚': true, '’': true, ''': true,
}
// 排除的标点黑名单
excludedPunct := map[rune]bool{
'!': true, '?': true, '@': true, '#': true,
'$': true, '%': true, '^': true, '&': true,
'*': true, '(': true, ')': true, '=': true,
'+': true, '[': true, ']': true, '{': true,
'}': true, '|': true, '\\': true, ';': true,
':': true, '"': true, '<': true, '>': true,
'/': true, '~': true, '`': true,
}
// 基本检查
if unicode.IsDigit(chr) || unicode.IsLetter(chr) || unicode.IsSpace(chr) {
return true
}
// 检查标点
if unicode.IsPunct(chr) {
if excludedPunct[chr] {
return false
}
return allowedPunct[chr]
}
// 其他可打印字符
return unicode.IsPrint(chr) && !unicode.IsControl(chr)
}
对于IsMark,通常不需要包含,因为它主要处理变音符号(如重音符号),这些已经包含在IsLetter的某些实现中。IsGraphic和IsPrint能更好地处理国际字符的显示需求。

