深入掌握Go语言中的正则表达式与字符串处理
Go语言中的正则表达式与模式匹配
在编程中,字符串处理是常见的需求之一,而正则表达式则是一个强大的工具,能够帮助我们实现复杂的字符串匹配、提取和替换功能。Go语言内置了对正则表达式的支持,通过regexp包,我们可以轻松实现模式匹配的各种操作。本文将详细介绍正则表达式在Go语言中的应用,并通过实际的代码示例来帮助你理解如何在日常编程中使用它。
正则表达式的基础概念
正则表达式是一种用于匹配字符串的模式,它基于一组规则或语法。Go语言中的正则表达式由regexp包提供,正则表达式的匹配引擎是基于有限自动机的,自动机可以是确定性或非确定性的。
- 确定性有限自动机(DFA):对于每一个状态和输入符号,都有一个确定的下一个状态。
- 非确定性有限自动机(NFA):对于相同的状态和输入符号,可能有多个可能的下一个状态。
正则表达式的主要作用是根据预定义的模式对字符串进行查找、提取、替换或删除。对于复杂的文本处理任务,正则表达式是一种高效且强大的工具。虽然它可以解决许多问题,但在某些情况下,正则表达式可能并不是最佳选择,需要合理选择工具。
正则表达式的语法
在深入代码之前,我们先简单介绍一下正则表达式的语法规则:
- 字符类:用方括号定义字符集合,例如
[abc]表示匹配’a’、'b’或’c’中的任意一个字符。 - 字符范围:在字符类中,可以使用范围表示法,例如
[a-z]表示匹配从’a’到’z’的任意小写字母。 - 重复次数:
*表示匹配0次或多次,+表示匹配1次或多次,?表示匹配0次或1次,{n,m}表示匹配n次到m次。 - 特殊字符:正则表达式中的一些符号具有特殊含义,例如
.表示任意字符,^表示字符串的开头,$表示字符串的结尾,\d表示数字,\w表示字母或数字字符。
简单的正则表达式示例
我们首先来看一个简单的例子:假设你需要从一行文本中提取出某一特定列的数据。为了实现这一点,可以使用空格作为分隔符,将文本行分割为多个字段,然后选择指定的列。
代码实现
package mainimport ("bufio""fmt""io""os""strconv""strings"
)func main() {arguments := os.Argsif len(arguments) < 2 {fmt.Printf("用法: selectColumn column <file1> [<file2> ... <fileN>]\n")os.Exit(1)}temp, err := strconv.Atoi(arguments[1])if err != nil {fmt.Println("列号不是整数:", temp)return}column := tempif column < 0 {fmt.Println("无效的列号!")os.Exit(1)}for _, filename := range arguments[2:] {fmt.Println("处理文件:", filename)f, err := os.Open(filename)if err != nil {fmt.Printf("打开文件出错 %s\n", err)continue}defer f.Close()r := bufio.NewReader(f)for {line, err := r.ReadString('\n')if err == io.EOF {break} else if err != nil {fmt.Printf("读取文件出错 %s", err)break}data := strings.Fields(line)if len(data) >= column {fmt.Println(data[column-1])}}}
}
程序说明
strings.Fields():这个函数用于将字符串按空白字符进行分割,返回一个字符串切片。空白字符包括空格、制表符、换行符等。bufio.NewReader():用于逐行读取文件的内容,通过ReadString('\n')可以按行读取文件,直到遇到EOF结束。
这个程序可以提取指定文本文件中的某一列数据,例如:
$ go run selectColumn.go 3 test.txt
正则表达式匹配日期时间格式
正则表达式不仅可以用于简单的列提取,还可以用来处理更加复杂的模式匹配任务。下面我们来看一个匹配和转换Apache服务器日志中的日期和时间格式的例子。
代码实现
package mainimport ("bufio""fmt""io""os""regexp""strings""time"
)func main() {arguments := os.Argsif len(arguments) == 1 {fmt.Println("请提供一个文本文件进行处理!")os.Exit(1)}filename := arguments[1]f, err := os.Open(filename)if err != nil {fmt.Printf("打开文件出错 %s", err)os.Exit(1)}defer f.Close()notAMatch := 0r := bufio.NewReader(f)for {line, err := r.ReadString('\n')if err == io.EOF {break} else if err != nil {fmt.Printf("读取文件出错 %s", err)}r1 := regexp.MustCompile(`.*\[(\d\d\/\w+\/\d\d\d\d:\d\d:\d\d:\d\d.*)\] .*`)if r1.MatchString(line) {match := r1.FindStringSubmatch(line)d1, err := time.Parse("02/Jan/2006:15:04:05 -0700", match[1])if err == nil {newFormat := d1.Format(time.Stamp)fmt.Print(strings.Replace(line, match[1], newFormat, 1))} else {notAMatch++}continue}r2 := regexp.MustCompile(`.*\[(\w+\-\d\d-\d\d:\d\d:\d\d:\d\d.*)\] .*`)if r2.MatchString(line) {match := r2.FindStringSubmatch(line)d1, err := time.Parse("Jan-02-06:15:04:05 -0700", match[1])if err == nil {newFormat := d1.Format(time.Stamp)fmt.Print(strings.Replace(line, match[1], newFormat, 1))} else {notAMatch++}}}fmt.Println(notAMatch, "行未匹配!")
}
程序说明
这个程序可以处理Apache日志中的两种日期格式,并将其转换为time.Stamp格式。具体来说:
regexp.MustCompile():用于编译正则表达式。MustCompile()与Compile()的区别在于,前者在正则表达式无效时会直接触发panic,而Compile()会返回错误。time.Parse():用于将日期字符串解析为time.Time类型。格式字符串如"02/Jan/2006:15:04:05 -0700"表示日期时间的格式。
运行该程序后,将输出日期格式转换后的日志内容:
$ go run changeDT.go log.txt
- - [Nov 21 19:28:09] "GET /file.zip HTTP/1.1" 200
2 行未匹配!
匹配IPv4地址
在网络编程中,匹配IP地址(特别是IPv4地址)是一个常见需求。我们可以使用正则表达式来捕捉文本中的IPv4地址。
代码实现
package mainimport ("bufio""fmt""io""net""os""regexp"
)func findIP(input string) string {partIP := "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"grammar := partIP + "\\." + partIP + "\\." + partIP + "\\." + partIPmatchMe := regexp.MustCompile(grammar)return matchMe.FindString(input)
}func main() {arguments := os.Argsif len(arguments) < 2 {fmt.Printf("用法: %s logFile\n", os.Args[0])os.Exit(1)}for _, filename := range arguments[1:] {f, err := os.Open(filename)if err != nil {fmt.Printf("打开文件出错 %s\n", err)os.Exit(1)}defer f.Close()r := bufio.NewReader(f)for {line, err := r.ReadString('\n')if err == io.EOF {break} else if err != nil {fmt.Printf("读取文件出错 %s", err)break}ip := findIP(line)if net.ParseIP(ip) != nil {fmt.Println(ip)}}}
}
程序说明
在这个程序中,我们使用正则表达式来捕捉IPv4地址,并通过net.ParseIP()进一步验证匹配到的IP地址是否有效。
net.ParseIP():用于验证一个字符串是否为有效的IP地址。
运行该程序可以从日志中提取所有IPv4地址,例如:
$ go run findIPv4.go /tmp/auth.log
192.168.1.1
10.0.0.1
Go语言中的字符串操作
虽然字符串并不是复合类型,但Go语言提供了丰富的字符串处理函数。在Go语言中,字符串是值类型,且默认支持UTF-8编码,这意味着你可以轻松处理Unicode字符。
字符串操作示例
package mainimport ("fmt""strings"
)func main() {fmt.Println(strings.ToUpper("hello world"))fmt.Println(strings.ToLower("HELLO WORLD"))fmt.Println(strings.TrimSpace(" Go语言 "))fmt.Println(strings.HasPrefix("golang", "go"))fmt.Println(strings.HasSuffix("golang", "lang"))fmt.Println(strings.Count("golang", "g"))
}
程序说明
ToUpper()和ToLower():用于将字符串转换为全大写或全小写。TrimSpace():移除字符串两端的空白字符。HasPrefix()和HasSuffix():检查字符串是否以某个子串开头或结尾。Count():统计子串在字符串中出现的次数。
这些函数为处理字符串提供了简单而高效的工具。
总结
本文介绍了Go语言中的正则表达式和字符串处理技术,包括基本的正则表达式语法、如何匹配日期时间格式、提取IPv4地址,以及字符串的常见操作。正则表达式在处理复杂字符串模式时具有极大的灵活性和高效性,而Go语言提供的强大库函数使得字符串处理变得更加简洁和易用。
正则表达式和字符串操作是任何编程语言中都必不可少的技能,掌握这些知识将使你在实际项目中处理文本和数据更加游刃有余。
相关文章:
深入掌握Go语言中的正则表达式与字符串处理
Go语言中的正则表达式与模式匹配 在编程中,字符串处理是常见的需求之一,而正则表达式则是一个强大的工具,能够帮助我们实现复杂的字符串匹配、提取和替换功能。Go语言内置了对正则表达式的支持,通过regexp包,我们可以…...
Docker进入容器运行命令
Docker进入容器运行命令 1. **使用 docker exec 进入容器并运行命令**语法:示例 1:进入容器并启动交互式 Bash 终端示例 2:在容器中运行单个命令 2. **使用 docker attach 进入容器**3. **使用 docker run 启动新容器并运行命令**4. **使用 d…...
[数据集][目标检测]机油泄漏检测数据集VOC+YOLO格式43张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):43 标注数量(xml文件个数):43 标注数量(txt文件个数):43 标注类别数…...
Python实现读取Excel数据详细教学版
Python实现读取Excel数据详细教学版 在处理数据和进行数据分析时,Excel文件是常见的数据载体。通过Python读取Excel数据,可以方便地对数据进行进一步的处理和分析。以下将详细介绍使用Python读取Excel数据的方法和相关库的使用,并提供具体代…...
【HarmonyOS】- 内存优化
文章目录 知识回顾前言源码分析1. onMemoryLevel2. 使用LRUCache优化ArkTS内存原理介绍3. 使用生命周期管理优化ArkTS内存4. 使用purgeable优化C++内存拓展知识1. Purgeable Memory总结知识回顾 前言 当应用程序占用过多内存时,系统可能会频繁进行内存回收和重新分配,导致应…...
【生日视频制作】保时捷车主提车交车仪式感AE模板修改文字软件生成器教程特效素材【AE模板】
生日视频制作教程保时捷车主提车交车仪式感AE模板修改文字特效广告生成神器素材祝福玩法AE模板工程 怎么如何做的【生日视频制作】保时捷车主提车交车仪式感AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤: 下载AE模板 安装AE软件 把AE模板导入…...
【自用14】C++俄罗斯方块-思路复盘3
在上篇降落函数中使用到了判断游戏是否结束的功能,因此这篇先从判断游戏是否结束开始 判断游戏是否结束 void failCheck(void){if(!moveable(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){setcolor(WHITE);setfont(45,0,_T("隶体"));outtextxy(75,300,_T(&quo…...
ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)
目录 一、数据聚合 1.1 DSL实现聚合 1.1.1 Bucket聚合 1.1.2 带条件聚合 1.1.3 Metric聚合 1.1.4 总结 2.1 RestClient实现聚合 2.1.1 Bucket聚合 2.1.2 带条件聚合 2.2.3 Metric聚合 一、数据聚合 聚合(aggregations)可以让我们极其方便的实…...
DBeaver 24.0 高阶用法
DBeaver 24.0 高阶用法 文章目录 DBeaver 24.0 高阶用法DBeaver 介绍功能一、元数据搜索功能二、仪表盘显示功能三、ER图功能四、导出数据最后 DBeaver 介绍 DBeaver 确实是一款功能强大的通用数据库管理工具,适合所有需要以专业方式处理数据的用户。它不仅提供了直…...
外卖会员卡项目骗局揭秘,你还在做梦吗?改醒醒了
大家好,我是鲸天科技千千,大家都知道我是做开发的,做互联网行业很多年了,平时会在这里给大家分享一些互联网相关的小技巧和小项目,感兴趣的给我点个关注。 关于外卖会员卡这个项目的一些骗局和套路,我真的…...
比较顺序3s1,3s2,4s1之间的关系
(A,B)---6*30*2---(0,1)(1,0) 分类A和B,让B全是0。当收敛误差为7e-4,收敛199次取迭代次数平均值,3s1为 3s2为 4s1为 3s1,3s2,4s1这3个顺序之间是否有什么联系 , 因为4s1可以按照结构加法 变换成与4s1内在…...
BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin
目录 [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法: [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问…...
数据库锁之行级锁、记录锁、间隙锁和临键锁
1. 行级锁 InnoDB 引擎支持行级锁,而MyISAM 引擎不支持行级锁,只支持表级锁。行级锁是基于索引实现的。 对于普通的select语句,是不会加记录锁的,因为它属于快照读,通过在MVCC中的undo log版本链实现。如果要在查询时对…...
基于yolov8的血细胞检测计数系统python源码+onnx模型+评估指标曲线+精美GUI界面
【算法介绍】 基于YOLOv8的血细胞检测与计数系统是一种利用深度学习技术,特别是YOLOv8目标检测算法,实现高效、准确血细胞识别的系统。该系统能够自动识别并计数图像或视频中的血细胞,包括红细胞、白细胞和血小板等,为医疗诊断提…...
【深度学习详解】Task3 实践方法论-分类任务实践 Datawhale X 李宏毅苹果书 AI夏令营
前言 综合之前的学习内容, 本篇将探究机器学习实践方法论 出现的问题及其原因 🍎 🍎 🍎 系列文章导航 【深度学习详解】Task1 机器学习基础-线性模型 Datawhale X 李宏毅苹果书 AI夏令营 【深度学习详解】Task2 分段线性模型-引入…...
乐凡北斗 | 手持北斗智能终端的作用与应用场景
在科技日新月异的今天,北斗智能终端作为一项融合了北斗导航系统与现代智能技术的创新成果,正悄然改变着我们的生活方式和工作模式。 北斗智能终端,是以北斗卫星导航系统为核心,集成了高精度定位、导航、授时等功能的智能设备。它…...
Linux:线程互斥
线程互斥 先看到一个抢票案例: class customer { public:int _ticket_num 0;pthread_t _tid;string _name; };int g_ticket 10000;void* buyTicket(void* args) {customer* cust (customer*)args;while(true){if(g_ticket > 0){usleep(1000);cout << …...
misc流量分析
一、wireshark语法 1、wireshark过滤语法 (1)过滤IP地址 ip.srcx.x..x.x 过滤源IP地址 ip.dstx.x.x.x 过滤目的IP ip.addrx.x.x.x 过滤某个IP (2)过滤端口号 tcp.port80tcp.srcport80 显示TCP的源端口80tcp.dstport80 显示…...
Linux驱动(五):Linux2.6驱动编写之设备树
目录 前言一、设备树是个啥?二、设备树编写语法规则1.文件类型2.设备树源文件(DTS)结构3.设备树源文件(DTS)解析 三、设备树API函数1.在内核中获取设备树节点(三种)2.获取设备树节点的属性 四、…...
算法【Java】 —— 前缀和
模板引入 一维前缀和 https://www.nowcoder.com/share/jump/9257752291725692504394 解法一:暴力枚举 在每次提供 l 与 r 的时候,都从 l 开始遍历数组,直到遇到 r 停止,这个方法的时间复杂度为 O(N * q) 解法二:前…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
