深入掌握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) 解法二:前…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
