Golang 统计字符串中数字字母数量的实现方法
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《Golang 统计字符串中数字字母数量的实现方法》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
1.需求说明
记录一下项目对用户 UGC 文本进行字数限制的具体实现。
不同的产品,出于种种原因,一般都会对用户输入的文本内容做字数限制。
- 出于产品定位,比如 140 字符限制的 Twitter,让内容保持简洁凝练,易于阅读;
- 出于用户的阅读体验,过多的文字会造成阅读疲劳,合适的字数能够提高阅读舒适度;
- 出于技术与成本的考虑,不设上限的 UGC 内容会引发一些潜在的问题,比如增加存储的成本,降低检索效率等。
回到自己的项目,是一个用户发帖的业务场景。产品同学给到的要求是:
- 帖子名称,限制在 25 个字;
- 帖子正文,限制在 1500 字;
- 关于字的说明:1 个汉字为一个字,一个 Emoji 表情相当于 1 个字,2 个数字/英文字母相当于 1 个字。
正常情况下,汉字,Emoji 字符,数字与英文字母都是单独的字符。这里 2 个数字/英文算作 1 个字,所以在计算字符串长度时,不能够使用 []rune 强转后来获取其长度,而是需要统计出数字与英文字母的数量,再加上其他字符数量,作为其长度。所以,要想实现产品同学的要求,关键是需要统计出用户输入文本中的数字与英文字母的数量。
2.实现
在 Golang,一般有两种方法。
2.1 ASCII 码值法
数字和英文字母的 ASCII 码值我们是知道的,通过对原字符串遍历,便可统计出数字/英文字母的数量。
// GetAlphanumericNumByASCII 根据 ASCII 码值获取字母数字数量。
func GetAlphanumericNumByASCII(s string) int {
num := int(0)
for i := 0; i
<h3>2.2 正则表达式</h3>
<p>我们可以利用 Golang 标准库包 regexp 获取指定表达式的字串数量。</p>
<pre class="brush:plain;">// GetAlphanumericNumByRegExp 根据正则表达式获取字母数字数量。
func GetAlphanumericNumByRegExp(s string) int {
rNum := regexp.MustCompile(`\d`)
rLetter := regexp.MustCompile("[a-zA-Z]")
return len(rNum.FindAllString(s, -1)) + len(rLetter.FindAllString(s, -1))
}
我们可以写个单测来验证下上面三个函数的正确性。
package string
import "testing"
func TestGetAlphanumericNumByASCII(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
want int
}{
{
name: "包含数字",
args: args{"108条梁山好汉"},
want: 3,
},
{
name: "包含字母",
args: args{"一百条梁山man"},
want: 3,
},
{
name: "包含数字与字母",
args: args{"108条梁山man"},
want: 6,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetAlphanumericNumByASCII(tt.args.s); got != tt.want {
t.Errorf("GetAlphanumericNumByASCII() = %v, want %v", got, tt.want)
}
})
}
}
func TestGetAlphanumericNumByASCIIV2(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
want int
}{
{
name: "包含数字",
args: args{"108条梁山好汉"},
want: 3,
},
{
name: "包含字母",
args: args{"一百条梁山man"},
want: 3,
},
{
name: "包含数字与字母",
args: args{"108条梁山man"},
want: 6,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetAlphanumericNumByASCIIV2(tt.args.s); got != tt.want {
t.Errorf("GetAlphanumericNumByASCII() = %v, want %v", got, tt.want)
}
})
}
}
func TestGetAlphanumericNumByRegExp(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
want int
}{
{
name: "包含数字",
args: args{"108条梁山好汉"},
want: 3,
},
{
name: "包含字母",
args: args{"一百条梁山man"},
want: 3,
},
{
name: "包含数字与字母",
args: args{"108条梁山man"},
want: 6,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetAlphanumericNumByRegExp(tt.args.s); got != tt.want {
t.Errorf("GetAlphanumericNumByRegExp() = %v, want %v", got, tt.want)
}
})
}
}
运行go test main/string命令,其中 main/string 为单元测试所在包的路径。输出如下:
ok main/string 0.355s
验证无误。
3.性能对比
上面提到的两种方法都可以用来获取字符串中数字与英文字母的数量,那么我们应该采用哪一种方法呢?
功能上没有差别,那么我们来看下性能对比吧。
func BenchmarkGetAlphanumericNumByASCII(b *testing.B) {
for n := 0; n
<p>运行上面的基准测试,输出如下:</p>
<blockquote><p>go test -bench=. -benchmem main/string</p>
<p>goos: windows<br>goarch: amd64<br>pkg: main/string<br>cpu: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz<br>BenchmarkGetAlphanumericNumByASCII-8 89540210 12.67 ns/op 0 B/op 0 allocs/op<br>BenchmarkGetAlphanumericNumByASCIIV2-8 63227778 19.11 ns/op 0 B/op 0 allocs/op<br>BenchmarkGetAlphanumericNumByRegExp-8 465954 2430 ns/op 1907 B/op 27 allocs/op<br>PASS<br>ok main/string 3.965s</p></blockquote>
<p>不测不知道,一测吓一跳。通过正则表达式的实现方式,代码虽然简洁,但是涉及多次内存配分,性能与 ASCII 码值法相比,差距非常之大,是 ASCII 码值法的 200 倍左右。所以从性能的考虑,推荐使用 ASCII 码值的方式获取数字字母数量。</p>
<p>ASCII 码值法有两种遍历方式,一种是按照字节遍历,一种是按照 rune 字符遍历。因为后者涉及 rune 字符的判断,所以性能会差一些。推荐使用按照字节遍历。</p>
<h2>4.小结</h2>
<p>本文给出了两种从字符串获取数字与字母数量的方法:</p>
- ASCII 码值。
- 正则表达式。
出于性能的考虑,推荐使用 ASCII 码值法,并使用字节遍历的方式。
此外,本文给出的两种方法,三种实现方式,相关源码已放置开源库 go-huge-util,可 import 直接使用。
package main
import (
"fmt"
huge "github.com/dablelv/go-huge-util"
)
func main() {
fmt.Println(huge.GetAlphanumericNumByASCII("108条梁山man")) // 6
fmt.Println(huge.GetAlphanumericNumByASCIIV2("108条梁山man")) // 6
fmt.Println(huge.GetAlphanumericNumByRegExp("108条梁山man")) // 6
}
参考文献
今天带大家了解了字符串、统计、字母、数字的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
Golang学习之反射机制的用法详解
- 上一篇
- Golang学习之反射机制的用法详解
- 下一篇
- 详解Go语言中Get/Post请求测试
-
- Golang · Go教程 | 9分钟前 |
- Golang协程同步之WaitGroup详解
- 354浏览 收藏
-
- Golang · Go教程 | 36分钟前 |
- Go语言实现文件压缩解压方法详解
- 213浏览 收藏
-
- Golang · Go教程 | 49分钟前 |
- Golang切片append扩容机制解析
- 383浏览 收藏
-
- Golang · Go教程 | 55分钟前 |
- Go语言高效筛选JSON数组技巧
- 325浏览 收藏
-
- Golang · Go教程 | 1小时前 | golang 并发安全 HTTP服务 投票系统 sync.RWMutex
- Golang实现投票系统教程详解
- 116浏览 收藏
-
- Golang · Go教程 | 1小时前 | golang module
- Golang依赖重新下载技巧全解析
- 452浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang文件读取错误处理技巧
- 313浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- GolangRESTAPI版本控制方法解析
- 472浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang中间件日志记录技巧
- 426浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang中介者模式降低耦合技巧
- 193浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- GolangSocket编程实战教程
- 355浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3176次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3388次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3417次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4522次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3796次使用
-
- 详解如何在Go语言中循环数据结构
- 2022-12-22 406浏览
-
- 详解Golang中字符串的使用
- 2023-01-01 370浏览
-
- 深度解密Go语言中字符串的使用
- 2022-12-24 160浏览
-
- Go实现快速生成固定长度的随机字符串
- 2023-02-24 432浏览
-
- Go如何实现json字符串与各类struct相互转换
- 2023-01-07 377浏览

