一个比官方strings.Title更精简高效的将字符串中所有单词首字母转换为大小写的go函数

本文主要是介绍一个比官方strings.Title更精简高效的将字符串中所有单词首字母转换为大小写的go函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在go语言的官方包 strings中,官方提供了Title函数用于将字符串中的单词首字母转换为大写,这个函数很绕,对于要转换的字符串先是一个Map循环,然后接着又是一个Map循环,且函数调函数掉了好多层,而且最新版本中已经标记为过时,推荐使用一个更绕的golang.org/x/text/cases包中的函数进行转换。

下面的函数使用了高效的正则来切割字符串,同时支持自定义切割字符来对字符串中的所有单词的首字母进行转换, 废话不多说,直接上代码:

// 转换字符串中单词的首字母大小写
//
//		s 待转换的字符串
//		sep 单词分隔符 如果指定了分隔符且不为空同时字符串中包含指定分隔符,则返回的字符串中的单词将会带上这个分隔符,否则分隔符全部会被设置为空
//	    isUpper 是否转换为大写 true 是, false 否(转换为小写)
//
// 使用示例:
//
//	ConvertWrodsFirstUpperLower("hello word","",true) // HelloWorld
//	ConvertWrodsFirstUpperLower("Hello Word"," ",false) // hello world
//
// 返回转换后的字符串
func ConvertWrodsFirstUpperLower(s, sep string, isUpper bool) string {// 定义切割字符串的正则regexp := `(\s+|\n|\r|\t|\f|\v|_|-|\b)`// 如果sep不为空,且字符串中包含用户提供的分隔符,则将分隔符放入到正则中if sep != "" && strings.Contains(s, sep) {regexp = fmt.Sprintf(`(%s|\s+|\n|\r|\t|\f|\v|_|-|\b)`, sep)} else {sep = "" // 其他情况将分隔符设置为空}re, err := GetRegexp(regexp)if err != nil {return s}ss := re.Split(s, -1) // 按照上面的正则切割字符串var sb strings.Buildersb.Grow(len(ss)) // 指定容量为切割后的切片个数for i, v := range ss {if v == "" {continue}r0 := []rune(v)[0]// 如果单词第一个rune是小写或者大写字母  大写字母 65-90  小写字母97-122if r0 <= 122 && ((r0 >= 'A' && r0 <= 'Z') || (r0 >= 'a' && r0 <= 'z')) {wr := falseif isUpper && 'a' <= r0 && r0 <= 'z' {wr = truer0 -= 'a' - 'A' // 转换为大写 小写字母比大写字母的ascii码大32  注意这里的转换大小写必须的前提} else if !isUpper && 'A' <= r0 && r0 <= 'Z' {wr = truer0 += 'a' - 'A' // 转换为小写}if wr {sb.WriteRune(r0)                      // 将转换后的单词第一个rune写入缓存sb.WriteString(string([]rune(v)[1:])) // 写入剩余的rune写入到缓存} else {sb.WriteString(v)}} else { // 非小写或者大写字母,直接原样写入sb.WriteString(v)}if sep != "" && i < len(ss)-1 {sb.WriteString(sep) // 写入单词分隔符}}if sb.Len() > 0 {return sb.String()}return s // 根据单词分隔符切割后的字符为空,原样返回
}// 将字符串中所有单词的第一个字母转换为大写
func Title(s string) string {if len(s) == 0 {return s}return ConvertWrodsFirstUpperLower(s, " ", true)
}// 将字符串中所有单词的第一个字母转换为小写
func UnTitle(s string) string {if len(s) == 0 {return s}return ConvertWrodsFirstUpperLower(s, " ", false)
}

上面代码实现并增强了官方的strings.Title的功能,可以说是Title的升级版, 完整代码见github仓库:http://github.com/tekintian/go-str-utils

官方的string.Title函数参考:

func Title(s string) string {// Use a closure here to remember state.// Hackish but effective. Depends on Map scanning in order and calling// the closure once per rune.prev := ' 'return Map(func(r rune) rune {if isSeparator(prev) {prev = rreturn unicode.ToTitle(r)}prev = rreturn r},s)
}// ToTitle maps the rune to title case.
func ToTitle(r rune) rune {if r <= MaxASCII {if 'a' <= r && r <= 'z' { // title case is upper case for ASCIIr -= 'a' - 'A'}return r}return To(TitleCase, r)
}
// To maps the rune to the specified case: [UpperCase], [LowerCase], or [TitleCase].
func To(_case int, r rune) rune {r, _ = to(_case, r, CaseRanges)return r
}func to(_case int, r rune, caseRange []CaseRange) (mappedRune rune, foundMapping bool) {if _case < 0 || MaxCase <= _case {return ReplacementChar, false // as reasonable an error as any}// binary search over rangeslo := 0hi := len(caseRange)for lo < hi {m := int(uint(lo+hi) >> 1)cr := caseRange[m]if rune(cr.Lo) <= r && r <= rune(cr.Hi) {delta := cr.Delta[_case]if delta > MaxRune {// In an Upper-Lower sequence, which always starts with// an UpperCase letter, the real deltas always look like://	{0, 1, 0}    UpperCase (Lower is next)//	{-1, 0, -1}  LowerCase (Upper, Title are previous)// The characters at even offsets from the beginning of the// sequence are upper case; the ones at odd offsets are lower.// The correct mapping can be done by clearing or setting the low// bit in the sequence offset.// The constants UpperCase and TitleCase are even while LowerCase// is odd so we take the low bit from _case.return rune(cr.Lo) + ((r-rune(cr.Lo))&^1 | rune(_case&1)), true}return r + delta, true}if r < rune(cr.Lo) {hi = m} else {lo = m + 1}}return r, false
}

 

这篇关于一个比官方strings.Title更精简高效的将字符串中所有单词首字母转换为大小写的go函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1066705

相关文章

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态