【go语言】regexp包,正则表达式

Go语言 regexp 包详解

Go 语言的 regexp 包提供了对正则表达式的支持。
正则表达式(regex)是一种字符串搜索模式,用来检查一个字符串是否符合某种特定的模式,或从中提取符合某种模式的子字符串。

1. regexp 包概述

regexp 包支持对字符串的匹配、搜索和替换。它基于 RE2 正则表达式引擎,性能优异,避免了回溯带来的性能瓶颈。
该包提供了多个函数来编译正则表达式并进行匹配、查找、替换等操作。

2. 常用函数

2.1 regexp.Compile(pattern string) (*Regexp, error)

该函数用于编译正则表达式字符串 pattern,并返回一个 Regexp 类型对象。如果正则表达式无效,会返回一个错误。
示例:

r, err := regexp.Compile(`\d+`)  // 匹配一个或多个数字
if err != nil {fmt.Println("Error compiling regex:", err)return
}

2.2 regexp.MustCompile(pattern string) *Regexp

该函数与 Compile 类似,不过如果正则表达式不合法,它会立即 panic。适合在启动时使用,确保正则表达式是合法的。
示例:

r := regexp.MustCompile(`\d+`)

2.3 r.MatchString(s string) bool

该方法检查给定的字符串 s 是否匹配正则表达式。如果匹配,返回 true,否则返回 false
示例:

r := regexp.MustCompile(`\d+`)
fmt.Println(r.MatchString("12345"))  // 输出:true
fmt.Println(r.MatchString("abc"))    // 输出:false

2.4 r.FindString(s string) string

该方法查找字符串中第一个匹配正则表达式的子字符串并返回。如果没有找到匹配项,则返回空字符串。
示例:

r := regexp.MustCompile(`\d+`)
fmt.Println(r.FindString("abc 12345 xyz")) // 输出:12345

2.5 r.FindAllString(s string, n int) []string

查找字符串中所有匹配正则表达式的子字符串,并返回一个字符串切片。如果 n 为 -1,则表示返回所有匹配的子串。
示例:

r := regexp.MustCompile(`\d+`)
fmt.Println(r.FindAllString("abc 123 4567 89", -1))  // 输出:[123 4567 89]

2.6 r.ReplaceAllString(s string, repl string) string

该方法用于替换字符串中所有匹配正则表达式的子字符串。repl 是替换的文本。
示例:

r := regexp.MustCompile(`\d+`)
result := r.ReplaceAllString("abc 123 4567 xyz", "#")
fmt.Println(result) // 输出:abc # # xyz

2.7 r.FindSubmatch(s string) [][]byte

查找第一个匹配的子字符串,并返回每个捕获组的内容(包括完整匹配)。返回的是一个二维字节切片,每个字节切片表示一个匹配项。
示例:

r := regexp.MustCompile(`(\d+)-(\d+)`)
match := r.FindSubmatch([]byte("abc 123-4567"))
fmt.Println(match)  // 输出:[[123-4567 123 4567]]

2.8 r.Split(s string, n int) []string

根据正则表达式分割字符串,返回一个字符串切片。n 参数表示最多分割的次数。
示例:

r := regexp.MustCompile(`\s+`)
fmt.Println(r.Split("this is a test", -1))  // 输出:[this is a test]

3. 正则表达式语法

Go 语言的 regexp 包使用的是 RE2 正则表达式引擎,它支持一些常见的正则表达式语法:

  • .:匹配除换行符以外的任何单个字符。
  • ^:匹配输入字符串的开始位置。
  • $:匹配输入字符串的结束位置。
  • *:匹配前一个字符零次或多次。
  • +:匹配前一个字符一次或多次。
  • ?:匹配前一个字符零次或一次。
  • {n,m}:匹配前一个字符至少 n 次,但不超过 m 次。
  • |:匹配左侧或右侧的表达式。
  • ():分组,括起来的部分作为一个整体进行匹配。
  • []:字符集,匹配括号内的任何一个字符。
  • \d:匹配一个数字,等同于 [0-9]
  • \w:匹配一个字母或数字字符,等同于 [a-zA-Z0-9_]
  • \s:匹配一个空白字符(包括空格、制表符、换行符等)。

4. 示例

示例 1:检查字符串是否符合正则表达式

package mainimport ("fmt""regexp"
)func main() {// 编译正则表达式r := regexp.MustCompile(`\d+`)// 检查字符串是否包含数字fmt.Println(r.MatchString("abc123"))  // 输出:truefmt.Println(r.MatchString("abc"))     // 输出:false
}

示例 2:提取数字

package mainimport ("fmt""regexp"
)func main() {// 编译正则表达式r := regexp.MustCompile(`\d+`)// 查找字符串中的第一个数字result := r.FindString("abc 12345 xyz")fmt.Println(result)  // 输出:12345
}

示例 3:替换字符串中的数字

package mainimport ("fmt""regexp"
)func main() {// 编译正则表达式r := regexp.MustCompile(`\d+`)// 替换数字为 #result := r.ReplaceAllString("abc 123 4567 xyz", "#")fmt.Println(result)  // 输出:abc # # xyz
}

示例 4:分割字符串

package mainimport ("fmt""regexp"
)func main() {// 编译正则表达式r := regexp.MustCompile(`\s+`)// 按空白字符分割字符串result := r.Split("this is a test", -1)fmt.Println(result)  // 输出:[this is a test]
}

5. 性能与注意事项

  • Go 的 regexp 包非常高效,特别是在处理大数据量时,RE2 正则表达式引擎避免了回溯带来的性能问题。
  • 使用正则表达式时需要谨慎,以避免过度复杂的模式导致性能瓶颈。

总结

regexp 包是 Go 语言中一个强大的工具,用于进行字符串模式匹配和替换操作。
通过使用该包,你可以灵活地处理复杂的字符串匹配任务,并且可以高效地进行文本处理。


案例

package _caseimport ("fmt""regexp"
)func RegexpCase() {test1()fmt.Println("------------")test2()
}func test2() {// 案例pattern := `^[a-z]+\[[0-9]+\]$`re := regexp.MustCompile(pattern)fmt.Println(re.MatchString("asdf[22114]"))// FindAll传入[]byte;// FindAllString传入stringbytes := re.FindAll([]byte("haha[1234]"), -1)fmt.Println(string(bytes[0]))re = regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)str := "今天日期:2024-10-21"replaced := re.ReplaceAllString(str, "我日你妈的")fmt.Println(replaced)
}// 常见的正则表达式字符及其含义
// 锚点字符:
//
// ^:匹配字符串的开始。例如,^abc 匹配以 "abc" 开头的字符串。
// $:匹配字符串的结束。例如,abc$ 匹配以 "abc" 结尾的字符串。
// 字符匹配:
//
// .(点号):匹配任意一个字符,除了换行符。例子:a.b 可以匹配 "a_b"、"a1b",但不能匹配 "ab"。
// [ ]:定义字符集合,匹配集合中的任意一个字符。例如,[abc] 匹配 "a"、"b" 或 "c"。
// [^ ]:排除字符集合,匹配集合外的任意字符。例如,[^abc] 匹配除 "a"、"b" 和 "c" 以外的任意字符。
// 量词:
//
// *:匹配前面的元素 0 次或多次。例如,a* 匹配空字符串、"a"、"aa" 等。
// +:匹配前面的元素 1 次或多次。例如,a+ 匹配 "a"、"aa"、"aaa" 等。
// ?:匹配前面的元素 0 次或 1 次。例如,a? 匹配空字符串或 "a"。
// {n}:匹配前面的元素恰好 n 次。例如,a{3} 匹配 "aaa"。
// {n,}:匹配前面的元素至少 n 次。例如,a{2,} 匹配 "aa"、"aaa"、"aaaa" 等。
// {n,m}:匹配前面的元素至少 n 次,但不超过 m 次。例如,a{2,4} 匹配 "aa"、"aaa" 或 "aaaa"。
// 字符类:
//
// \d:匹配任意数字,等同于 [0-9]。
// \D:匹配非数字字符,等同于 [^0-9]。
// \w:匹配字母、数字或下划线,等同于 [a-zA-Z0-9_]。
// \W:匹配非字母、数字或下划线字符,等同于 [^a-zA-Z0-9_]。
// \s:匹配任意空白字符(包括空格、制表符、换行符等)。
// \S:匹配任意非空白字符。
// 分组和选择:
//
// ( ):定义捕获组,匹配的内容可以在后续操作中引用。例如,(abc) 匹配 "abc"。
// |:逻辑或,表示左右两边任意一个匹配即可。例如,a|b 匹配 "a" 或 "b"。
// 反斜杠转义:
//
// \:反斜杠用于转义特殊字符。例如,\. 匹配字符 ".",而不是表示任意字符的点号。
// 特殊字符类:
//
// \b:匹配单词边界。例如,\bword\b 匹配完整的 "word",但不会匹配 "sword" 中的 "word"。
// \B:匹配非单词边界。
// 举例说明
// ^\d{3}-\d{2}-\d{4}$:匹配符合格式的社会保障号(比如 "123-45-6789")。
//
// ^:匹配字符串的开始。
// \d{3}:匹配 3 个数字。
// -:匹配字符 -。
// \d{2}:匹配 2 个数字。
// \d{4}:匹配 4 个数字。
// $:匹配字符串的结束。
// ([A-Z][a-z]+):匹配以大写字母开头的单词(如 "Apple")。
//
// [A-Z]:匹配一个大写字母。
// [a-z]+:匹配一个或多个小写字母。
// ( ):定义捕获组。
func test1() {// Compile解析并返回一个正则表达式。如果成功返回,该Regexp就可用于匹配文本。re := regexp.MustCompile(".com")// FindStringfmt.Println(re.FindString("(cainiao.com)"))fmt.Println(re.FindString("(cainiao.dz)"))fmt.Println(re.FindString("(cainiao1.com1)"))// FindStringIndex return符合正则表达式的字符的索引,左闭右开fmt.Println(re.FindStringIndex("google.com"))fmt.Println(re.FindStringIndex("abc.org"))fmt.Println(re.FindStringIndex("fb.com"))// FindStringSubmatch 该方法返回具有最左边匹配项和匹配组的字符串。找不到返回空字符串// ([a-z]+)称为匹配组re1 := regexp.MustCompile("f([a-z]+)ing")re2 := regexp.MustCompile("f([a-z]+)ing")fmt.Println(re1.FindStringSubmatch("flying1"))fmt.Println(re1.FindStringSubmatch("abcfloatingxyz"))fmt.Println(re2.FindStringSubmatch("flying1"))fmt.Println(re2.FindStringSubmatch("abcfloatingxyz"))fmt.Println("-----------")pattern := "([a-z]+)"regex := regexp.MustCompile(pattern)// FindStringSubmatch 只会返回一个 包含的匹配结果,和一个 匹配组 合成的一个切片// len:2matches := regex.FindStringSubmatch("apple banana orange")fmt.Println(matches[0])fmt.Println(matches[1])//fmt.Println(matches[2])//fmt.Println(matches[3])// 如果想要匹配所有符合正则表达式的值,要用FindAllStringSubmatch// n为-1时,匹配所有符合条件的字符串,n不为-1时,表示只匹配n次// 会返回一个二维切片matches1 := regex.FindAllStringSubmatch("apple banana orange", -1)fmt.Println(matches1)// 遍历匹配结果for i, match := range matches1 {fmt.Printf("匹配 %d 结果:%s\n", i, match[0])fmt.Printf("捕获组 %d 结果:%s\n", i, match[1])}// 命名捕获组语法// (?P<name>pattern)// name:捕获组名称,pattern:捕获组模式pattern = "(?P<fruit>[a-z]+)"// 建立正则表达式re3 := regexp.MustCompile(pattern)// 匹配单个值matches = re3.FindStringSubmatch("apple banana orange")fruit := matches[re3.SubexpIndex("fruit")]fmt.Println(fruit)// 匹配多个值matches1 = re3.FindAllStringSubmatch("apple banana orange", -1)for i, match := range matches1 {fruit = match[re3.SubexpIndex("fruit")]fmt.Printf("匹配结果%d:%s\n", i, match[0])fmt.Printf("捕获组组%d:%s\n", i, fruit)}// regexp.Match() 判断在[]byte中能否找到给定正则表达式的值,返回bool和err// .*:表示任意数量的任意字符(包括 0 个字符),可以匹配任何字符,除了换行符// "^abc.*z$"含义:// 匹配以abc开头中间任意个数任意类型字符(除换行符外)以z结尾的字符串matched, err := regexp.Match("^abc.*z$", []byte("abcdeeffgz"))fmt.Println(matched, err)matched, err = regexp.Match("^abc.*z$", []byte("bcdefgz"))fmt.Println(matched, err)// regexp.MatchString()类似regexp.Match()不过他只传字符串,而Match只传[]byte
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/64100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数字花园】个人知识库网站搭建:①netlify免费搭建数字花园

目录 [[数字花园]]的构建原理包括三个步骤&#xff1a;五个部署方案教程相关教程使用的平台 步骤信息管理 这里记录的自己搭建数字花园&#xff08;在线个人知识库&#xff09;的经历&#xff0c;首先尝试的是网上普遍使用的方法&#xff0c;也就是本篇文章介绍的。 后面会继续…

《探秘开源气味数据库:数字世界里的“气味宝藏”》

《探秘开源气味数据库&#xff1a;数字世界里的“气味宝藏”》 一、开源气味数据库的兴起背景&#xff08;一&#xff09;技术发展的推动&#xff08;二&#xff09;市场需求的催生 二、常见的开源气味数据库介绍&#xff08;一&#xff09;GS-LF 香精香料数据库&#xff08;二…

【0x000C】HCI_Link_Key_Request_Negative_Reply 命令详解

目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Link_Key_Request_Negative_Reply命令格式 2.2. BD_ADDR 三、返回事件及参数 3.1. 生成的事件 3.2. BD_ADDR 2.3. Status 四、命令执行流程场景 4.1. 命令触发条件 4.2. 命令组装与发送 4.3. 控制器接收与处理 …

C#里怎么样删除字典里多项元素?

当我们使用字典比较多的情况,一般来说,就是为了提高查询的速度。 比如一个服务器,有多个TCP连接上来,每次要通过IP地址来访问这些连接对象, 就需要查找。 如果采用列表来保存,就只能遍历来查询到连接对象。 如果采用字典,就可以快速地通过字典键来查询到对象,其实这…

数字产业化和产业数字化到底是什么?

“数字产业化”和“产业数字化”在很多官方文件和领导人讲话中都是成对出现的&#xff0c;这两个术语看起来非常相似&#xff0c;但它们作为数字经济的两个重要组成部分&#xff0c;既有联系又有区别。 在谈数字产业化和产业数字化之前&#xff0c;我这里需要先给大家介绍一个概…

mysql、postgresql、oceanbase调优

一、mysql 1、my.cnf [mysqld_safe] log-error=/data/mysql/log/mysql.log pid-file=/data/mysql/run/mysqld.pid[client] socket=/data/mysql/run/mysql.sock default-character-set=utf8[mysqld] basedir=/usr/local/mysql tmpdir=/data/mysql/tmp datadir=/data/mysql/dat…

npm或yarn包配置地址源

三种方法 1.配置.npmrc 文件 在更目录新增.npmrc文件 然后写入需要访问的包的地址 2.直接yarn.lock文件里面修改地址 简单粗暴 3.yarn install 的时候添加参数 设置包的仓库地址 yarn config set registry https://registry.yarnpkg.com 安装&#xff1a;yarn install 注意…

文件上传之黑名单检测

一般情况下&#xff0c;代码文件里会有一个数组或者列表&#xff0c;该数组或者列表里会包含一些非法的字符或者字符串&#xff0c;当数据包中含有符合该列表的字符串时&#xff0c;即认定该数据包是非法的。 ​​ 一.如何判断是否为黑名单检测 黑名单是有限的&#xff0c;可以…

扩展tinyplay使其自适应不同声道数量的媒体

android原来的tinyplay代码&#xff0c;如果遇到播放媒体的 声道数量与打开pcm的声道数量不匹配的情况&#xff0c;会没法继续播放。 本例扩展了tinyplay的代码&#xff0c;将不同声道的音频数据展开/压缩到pcm设备支持的数据&#xff0c;再写入pcm设备。 bplay.c #include &…

光控资本:锂电排产上行 AI手机有望快速渗透

AI手机有望快速渗透 据赛迪参谋猜想&#xff0c;2024年AI手机的出货量估量将会抵达1.5亿部&#xff0c;占全球智能手机总出货量13%&#xff0c;到2027年&#xff0c;全球AI手机销售量有望跨过5.9亿部&#xff0c;占全球智能手机总出货量的比重跨过50%。 跟着硬件根底夯实、端侧…

el-table 动态计算合并行

原始表格及代码 <el-table:data"tableData"class"myTable"header-row-class-name"tableHead" ><el-table-column prop"date" label"日期"> </el-table-column><el-table-column prop"name" …

druid.properties图标是齿轮

一、问题 在IDEA中&#xff0c; druid.properties图标是齿轮 二、原因 2023版本开始&#xff0c;IDEA新的UI的问题 三、解决方法 1、点击右上角的齿轮图标 2、点击Settings 3、Appearance & Behavior---->New UI---->取消勾选“Enable new UI”---->右下角OK 4…

龙海家园地面停车场探寻2

在南山前海上班2年多了&#xff0c;到现在最喜欢的小区还是龙海家园小区。龙海家园小区是深圳目前最大的公共保障性租赁住房小区,目前居住有约2.6万人。而小区的停车位是远远不够的。之前一直很好奇车子可以停哪里。 后面加班之余经常去小区吃饭和转转。发现龙海家园小区与对面…

群控系统服务端开发模式-应用开发-操作记录功能开发

一、开放路由 在根目录下route文件夹下修改app.php文件&#xff0c;代码如下&#xff1a; // 操作日志Route::get(token/get_list,permission.Token/getList);// 获取操作日志列表Route::post(token/get_all,permission.Token/getAll);// 获取操作日志所有数据Route::post(toke…

SQLite Update 语句

SQLite Update 语句 SQLite 的 UPDATE 语句用于更新数据库表中的现有记录。使用 UPDATE 语句&#xff0c;您可以修改一个或多个列的值。本教程将详细介绍如何使用 SQLite UPDATE 语句&#xff0c;包括语法、示例以及一些最佳实践。 语法 SQLite UPDATE 语句的基本语法如下&a…

SQL 单表查询练习题(一)

在 SQL 的学习过程中&#xff0c;单表查询是非常重要的基础部分&#xff0c;下面为大家分享一些单表查询的练习题以及对应的正确答案&#xff0c;希望能帮助大家更好地掌握相关知识。 一、题目及答案详情 1. 查询课程表中&#xff0c;没有前序课程的课程信息&#xff0c;查询…

评估一套呼叫中心大模型呼出机器人的投入回报比?

评估一套呼叫中心大模型呼出机器人的投入回报比&#xff1f; 原作者&#xff1a;开源呼叫中心FreeIPCC&#xff0c;其Github&#xff1a;https://github.com/lihaiya/freeipcc 评估一套呼叫中心大模型呼出机器人的投入回报比&#xff08;ROI&#xff09;&#xff0c;是一个涉…

探索 HTTP 请求头中的 “Host” 字段及其安全风险

探索 HTTP 请求头中的 “Host” 字段及其安全风险 大家好&#xff0c;今天我们来聊聊 HTTP 请求头中的“Host”字段&#xff0c;以及它的使用方法和安全风险。 什么是Host字段 在 HTTP 请求头中&#xff0c;“Host”字段是一个至关重要的部分。它告诉服务器&#xff0c;我们…

Type-C接口电热毯的创新之旅

在科技日新月异的今天&#xff0c;智能家居产品正逐步渗透到我们生活的每一个角落&#xff0c;从智能灯光到温控系统&#xff0c;无一不展现着科技带来的便捷与舒适。而在这个追求高效与智能化的浪潮中&#xff0c;一款结合了最新科技元素的电热毯——Type-C接口电热毯&#xf…

计算机网络知识点全梳理(一.TCP/IP网络模型)

目录 TCP/IP网络模型概述 应用层 什么是应用层 应用层功能 应用层协议 传输层 什么是传输层 传输层功能 传输层协议 网络层 什么是网络层 网络层功能 网络层协议 数据链路层 什么是数据链路层 数据链路层功能 物理层 物理层的概念和功能 TCP/IP网络模型概述…