strings.Title的使用
在传统中,我们可以通过如下形式将每个单词的首字母变成大写字母,示例如下:
代码语言:javascript复制func TestTitle(t *testing.T) {
fmt.Println(strings.Title("hello world"))
fmt.Println(strings.Title("hell golang"))
fmt.Println(strings.Title("xiexie"))
}
执行上述代码,对应打印结果如下:
代码语言:javascript复制Hello World
Hell Golang
Xiexie
可见,strings.Title 会将每个单词的首字母变成大写字母。
strings中还有两个函数:ToTitle和ToUpper,功能类似,所有字符全部变成大写。
示例如下:
代码语言:javascript复制func TestTitle2(t *testing.T) {
fmt.Println(strings.ToTitle("hello world"))
fmt.Println(strings.ToUpper("hello golang"))
}
输出如下:
代码语言:javascript复制HELLO WORLD
HELLO GOLANG
但在IDE的提示和官方文档中都可以看到Title函数已经被废弃掉了。主要原因是:strings.Title的规则是使用单词边界,不能正确处理Unicode标点。
示例如下:
代码语言:javascript复制func TestTitle3(t *testing.T) {
fmt.Println(strings.Title("here comes o'brian"))
}
输出如下:
代码语言:javascript复制Here Comes O'Brian
可以看出”B“也被大写了。
strings.Title的两大问题:
- 无法正确处理Unicode标点符号。
- 不考虑特定人类语言的大写规则。
Unicode问题
关于Unicode标点符号再来看一个示例:
代码语言:javascript复制func TestTitle5(t *testing.T) {
a := strings.Title("go.gou2024go")
b := "Go.Gou2024Go"
if a != b {
fmt.Printf("%s != %sn", a, b)
}
}
输出结果为:
代码语言:javascript复制Go.Go․go != Go.Go․Go
变量a转换处理的结果是“Go.Go․go”,但按照实际的诉求应当为“Go.Go․Go”。
特定语言问题
代码如下:
代码语言:javascript复制func TestTitle6(t *testing.T) {
fmt.Println(strings.Title("ijsland"))
}
在荷兰语的单词中,“ijsland”应大写为“IJsland”,但结果转换为“Ijsland”。
golang.org/x/text/cases包
strings.Title的文档中提到了,可以通过golang.org/x/text/cases 来替代strings.Title的功能,也就是cases.Title。
cases.Title提供了基于特定语言的case map,其中有一个Title函数,签名如下:
代码语言:javascript复制// Title returns a Caser for language-specific title casing. It uses an
// approximation of the default Unicode Word Break algorithm.
func Title(t language.Tag, opts ...Option) Caser {
return Caser{makeTitle(t, getOpts(opts...))}
}
第一个参数是 language.Tag类型,表示BCP 47种语言标记。它用于指定特定语言或区域设置的实例。
第二个参数是不定参数,类型是Option。
使用前需要先引入“golang.org/x/text” 的类库。比如:
代码语言:javascript复制require golang.org/x/text v0.11.0
使用实例如下:
代码语言:javascript复制import (
"fmt"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"strings"
"testing"
)
func TestTitle4(t *testing.T) {
caser := cases.Title(language.English)
fmt.Println(caser.String("here comes o'brian"))
}
输出结果如下:
代码语言:javascript复制Here Comes O'brian
对照一下strings.Title,可以看出“brain”的“b”在这里成功识别,并未被大写。
cases.Title的返回类型是Caser结构体,调用它的String方法,该方法接收一个字符串,并返回一个经过Caser处理过后的字符串。