一个比官方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

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp