Go 语言入门学习之正则表达式

目录
  • 前言
  • 什么是正则表达式
  • MatchString 函数
  • Compile 函数
  • MustCompile 函数
  • FindAllString 函数
  • FindAllStringIndex 函数
  • Split 函数
  • Go 正则表达式捕获组
  • 正则表达式替换字符串
  • ReplaceAllStringFunc 函数
  • 总结

前言

在计算中,我们经常需要将特定模式的字符或字符子集匹配为另一个字符串中的字符串。此技术用于使用特别的语法来搜索给定字符串中的特定字符集。

如果搜索到的模式匹配,或者在目标字符串中找到给定的子集,则搜索被称为成功;否则被认为是不成功的。

什么是正则表达式

正则表达式(或 RegEx)是一个特殊的字符序列,它定义了用于匹配特定文本的搜索模式。在 Golang 中,有一个内置的正则表达式包: ​​regexp​​ 包,其中包含所有操作列表,如过滤、修改、替换、验证或提取。

正则表达式可以用于文本搜索和更高级的文本操作。正则表达式内置于 grep 和 sed 等工具,vi 和 emacs 等文本编辑器,Go、Java 和 Python 等编程语言中。表达式的语法主要遵循这些流行语言中使用的已建立的 RE2 语法。 RE2 语法是 PCRE 的一个子集,有各种注意事项。

MatchString 函数

​MatchString()​​ 函数报告作为参数传递的字符串是否包含正则表达式模式的任何匹配项。

package main
import (
"fmt"
"log"
"regexp"
)
func main() {
words := [...]string{"Seven", "even", "Maven", "Amen", "eleven"}
for _, word := range words {
found, err := regexp.MatchString(".even", word)
if err != nil {
log.Fatal(err)
}
if found {
fmt.Printf("%s matches\n", word)
} else {
fmt.Printf("%s does not match\n", word)
}
}
}

运行该代码:

Seven matches
even does not match
Maven does not match
Amen does not match
eleven matches

但同时我们能看到编辑器有提示:

编译器已经开始提醒我们,​​MatchString​​ 直接使用性能很差,所以考虑使用 ​​regexp.Compile​​ 函数。

Compile 函数

​Compile​​ 函数解析正则表达式,如果成功,则返回可用于匹配文本的 Regexp 对象。编译的正则表达式产生更快的代码。

​MustCompile​​ 函数是一个便利函数,它编译正则表达式并在无法解析表达式时发生 panic。

package main
import (
"fmt"
"log"
"regexp"
)
func main() {
words := [...]string{"Seven", "even", "Maven", "Amen", "eleven"}
re, err := regexp.Compile(".even")
if err != nil {
log.Fatal(err)
}
for _, word := range words {
found := re.MatchString(word)
if found {
fmt.Printf("%s matches\n", word)
} else {
fmt.Printf("%s does not match\n", word)
}
}
}

在代码示例中,我们使用了编译的正则表达式。

re, err := regexp.Compile(".even")

即使用 ​​Compile​​ 编译正则表达式。然后在返回的正则表达式对象上调用 ​​MatchString​​ 函数:

found := re.MatchString(word)

运行程序,能看到同样的代码:

Seven matches
even does not match
Maven does not match
Amen does not match
eleven matches

MustCompile 函数

package main
import (
"fmt"
"regexp"
)
func main() {
words := [...]string{"Seven", "even", "Maven", "Amen", "eleven"}
re := regexp.MustCompile(".even")
for _, word := range words {
found := re.MatchString(word)
if found {
fmt.Printf("%s matches\n", word)
} else {
fmt.Printf("%s does not match\n", word)
}
}
}

FindAllString 函数

​FindAllString​​ 函数返回正则表达式的所有连续匹配的切片。

package main
import (
"fmt"
"os"
"regexp"
)
func main() {
var content = `Foxes are omnivorous mammals belonging to several genera
of the family Canidae. Foxes have a flattened skull, upright triangular ears,
a pointed, slightly upturned snout, and a long bushy tail. Foxes live on every
continent except Antarctica. By far the most common and widespread species of
fox is the red fox.`
re := regexp.MustCompile("(?i)fox(es)?")
found := re.FindAllString(content, -1)
fmt.Printf("%q\n", found)
if found == nil {
fmt.Printf("no match found\n")
os.Exit(1)
}
for _, word := range found {
fmt.Printf("%s\n", word)
}
}

在代码示例中,我们找到了单词 fox 的所有出现,包括它的复数形式。

re := regexp.MustCompile("(?i)fox(es)?")

使用 (?i) 语法,正则表达式不区分大小写。 (es)?表示“es”字符可能包含零次或一次。

found := re.FindAllString(content, -1)

我们使用 ​​FindAllString​​ 查找所有出现的已定义正则表达式。第二个参数是要查找的最大匹配项; -1 表示搜索所有可能的匹配项。

运行结果:

["Foxes" "Foxes" "Foxes" "fox" "fox"]
Foxes
Foxes
Foxes
fox
fox

FindAllStringIndex 函数

package main
import (
"fmt"
"regexp"
)
func main() {
var content = `Foxes are omnivorous mammals belonging to several genera
of the family Canidae. Foxes have a flattened skull, upright triangular ears,
a pointed, slightly upturned snout, and a long bushy tail. Foxes live on every
continent except Antarctica. By far the most common and widespread species of
fox is the red fox.`
re := regexp.MustCompile("(?i)fox(es)?")
idx := re.FindAllStringIndex(content, -1)
for _, j := range idx {
match := content[j[0]:j[1]]
fmt.Printf("%s at %d:%d\n", match, j[0], j[1])
}
}

在代码示例中,我们在文本中找到所有出现的 fox 单词及其索引。

Foxes at 0:5
Foxes at 81:86
Foxes at 196:201
fox at 296:299
fox at 311:314

Split 函数

​Split​​ 函数将字符串切割成由定义的正则表达式分隔的子字符串。它返回这些表达式匹配之间的子字符串切片。

package main
import (
"fmt"
"log"
"regexp"
"strconv"
)
func main() {
var data = `22, 1, 3, 4, 5, 17, 4, 3, 21, 4, 5, 1, 48, 9, 42`
sum := 0
re := regexp.MustCompile(",\s*")
vals := re.Split(data, -1)
for _, val := range vals {
n, err := strconv.Atoi(val)
sum += n
if err != nil {
log.Fatal(err)
}
}
fmt.Println(sum)
}

在代码示例中,我们有一个逗号分隔的值列表。我们从字符串中截取值并计算它们的总和。

re := regexp.MustCompile(",\s*")

正则表达式包括一个逗号字符和任意数量的相邻空格。

vals := re.Split(data, -1)

我们得到了值的一部分。

for _, val := range vals {
n, err := strconv.Atoi(val)
sum += n
if err != nil {
log.Fatal(err)
}
}

我们遍历切片并计算总和。切片包含字符串;因此,我们使用 ​​strconv.Atoi​​ 函数将每个字符串转换为整数。

运行代码:

189

Go 正则表达式捕获组

圆括号 () 用于创建捕获组。这允许我们将量词应用于整个组或将交替限制为正则表达式的一部分。为了找到捕获组(Go 使用术语子表达式),我们使用 ​​FindStringSubmatch​​ 函数。

package main
import (
"fmt"
"regexp"
)
func main() {
websites := [...]string{"webcode.me", "zetcode.com", "freebsd.org", "netbsd.org"}
re := regexp.MustCompile("(\w+)\.(\w+)")
for _, website := range websites {
parts := re.FindStringSubmatch(website)
for i, _ := range parts {
fmt.Println(parts[i])
}
fmt.Println("---------------------")
}
}

在代码示例中,我们使用组将域名分为两部分。

re := regexp.MustCompile("(\w+)\.(\w+)")

我们用括号定义了两个组。

parts := re.FindStringSubmatch(website)

​FindStringSubmatch​​ 返回包含匹配项的字符串切片,包括来自捕获组的字符串。

运行代码:

$ go run capturegroups.go
webcode.me
webcode
me
---------------------
zetcode.com
zetcode
com
---------------------
freebsd.org
freebsd
org
---------------------
netbsd.org
netbsd
org
---------------------

正则表达式替换字符串

可以用 ​​ReplaceAllString​​ 替换字符串。该方法返回修改后的字符串。

package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"regexp"
"strings"
)
func main() {
resp, err := http.Get("http://webcode.me")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
content := string(body)
re := regexp.MustCompile("<[^>]*>")
replaced := re.ReplaceAllString(content, "")
fmt.Println(strings.TrimSpace(replaced))
}

该示例读取网页的 HTML 数据并使用正则表达式去除其 HTML 标记。

resp, err := http.Get("http://webcode.me")

我们使用 http 包中的 Get 函数创建一个 GET 请求。

body, err := ioutil.ReadAll(resp.Body)

我们读取响应对象的主体。

re := regexp.MustCompile("<[^>]*>")

这个模式定义了一个匹配 HTML 标签的正则表达式。

replaced := re.ReplaceAllString(content, "")

我们使用 ReplaceAllString 方法删除所有标签。

ReplaceAllStringFunc 函数

​ReplaceAllStringFunc​​ 返回一个字符串的副本,其中正则表达式的所有匹配项都已替换为指定函数的返回值。

package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
content := "an old eagle"
re := regexp.MustCompile(`[^aeiou]`)
fmt.Println(re.ReplaceAllStringFunc(content, strings.ToUpper))
}

在代码示例中,我们将 ​​strings.ToUpper​​ 函数应用于字符串的所有字符。

$ go run replaceallfunc.go
aN oLD eaGLe

总结

模式匹配在根据基于正则表达式和语法的特定搜索模式在字符串中搜索某些字符集时起着重要作用。

匹配的模式允许我们从字符串中提取所需的数据并以我们喜欢的方式对其进行操作。理解和使用正则表达式是处理文本的关键。

在实践中,程序员会保留一组常用的正则表达式来匹配电子邮件、电话号码等,并在需要时使用和重用它。

到此这篇关于Go 语言入门学习之正则表达式的文章就介绍到这了,更多相关Go正则表达式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go语言正则表达式的使用详解

    正则表达式是一种进行模式匹配和文本操纵的功能强大的工具.正则表达式灵活.易用,按照它的语法规则,随需构造出的匹配模式就能够从原始文本中筛选出几乎任何你想要得到的字符组合. 准则 默认是最短匹配,只要字符串满足条件就返回. 如果没有匹配到,都是返回为nil. 如果需要做最长匹配,调用Longest()函数. 正则表达式功能:匹配(macth),查找(find)和替换(replace). 存在长度选择的函数,传入<0的数字表示匹配全部. 使用regexp调用 Match,MatchReader和 M

  • 解决新django中的path不能使用正则表达式的问题

    新版的path 虽然 取代了 之前的url,但是在写路由的时候不能在路由中直接写正则表达式,不然会找不到页面. 解决方法 使用re_path from django.urls import re_path,path urlpatterns = [ path('admin/', admin.site.urls), re_path('edit/(\d+)',views.edit), ] 这样就可以 使用正则了. 以上这篇解决新django中的path不能使用正则表达式的问题就是小编分享给大家的全部内

  • Golang爬虫及正则表达式的实现示例

    目录 字符 数量限定 其他 爬虫 补充:正则表达式加golang爬虫爬取经典案例豆瓣top250 最近学习go,爬取网站数据用到正则表达式,做个总结: Go中正则表达式采用RE2语法(具体是啥咱也不清楚): 字符 . --匹配任意字符 e.g: abc. 结果: abcd,abcx,abc9; [] --匹配括号中任意一个字符 e.g: [abc]d 结果:ad,cd,1d: - --[-]中表示范围 e.g: [A-Za-z0-9]: ^ --[^]中表示除括号中的任意字符 e.g:[^xy]

  • Django框架教程之正则表达式URL误区详解

    前言 利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护.但这其中可能会有一些误区,下面就来给大家总结下. 问题: 我学习的视频大概是2015年录的,里面用的Django版本比较老关于正则表达式URL这一块都是用的url("url(r'^admin/', admin.site.urls),")方法.而我自己练习的时候是下载的最新版本,而正则表达式URL用的确实path("pat

  • 浅析golang 正则表达式

    Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型.编译型语言.Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算. 罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor.Russ Cox加入项目.Go是

  • 在Django中URL正则表达式匹配的方法

    Django框架中的URL分发采用正则表达式匹配来进行,以下是正则表达式的基本规则: 官方演示代码: from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/

  • Go语言正则表达式用法实例小结【查找、匹配、替换等】

    本文实例讲述了Go语言正则表达式用法.分享给大家供大家参考,具体如下: Go语言的正则表达式使用很简单,示例代码: 复制代码 代码如下: package test import (     "fmt"     "regexp" ) func RegixBase() {     //findTest()     //findIndexTest()     //findStringTest()     //findChinesString()     //findNum

  • Go 语言入门学习之正则表达式

    目录 前言 什么是正则表达式 MatchString 函数 Compile 函数 MustCompile 函数 FindAllString 函数 FindAllStringIndex 函数 Split 函数 Go 正则表达式捕获组 正则表达式替换字符串 ReplaceAllStringFunc 函数 总结 前言 在计算中,我们经常需要将特定模式的字符或字符子集匹配为另一个字符串中的字符串.此技术用于使用特别的语法来搜索给定字符串中的特定字符集. 如果搜索到的模式匹配,或者在目标字符串中找到给定的

  • Java新手入门学习之正则表达式

    一.概述 1.概念:符合一定规则的表达式. 2.作用:用于专门操作字符串. 3.特点:用于一些特定的符号来表示一些代码操作,这样就可以简化代码书写. 4.好处:可简化对字符串的基本操作. 5.弊端:符号定义越多,正则越长,阅读性越差. 二.常用符号: 说明:X表示字符X或者匹配的规则. 一)字符 构造 匹配 \ 反斜线字符 \t 制表符 \n 回车符 \f 换页符 二)字符类 表达式 释义 [abc] a.b或c(简单类) [^abc] 任何字符,除了a.b或c(否定) [a-zA-Z] a到z

  • C语言入门学习笔记之typedef简介

    在单片机和操作系统中 typedef 会经常用到,它可以为某一个类型自定义名称.和#define比较类似.但是又有不同的地方. typedef 创建的符号只能用于数据类型,不能用于值.而#define 创建的符号可以用于值. typedef 是由编译器来解释,而不是预处理器. typedef 使用起来更加灵活. 下面使用typedef定义一个数据类型 int main() { typedef unsigned char BYTE; BYTE c = 10; printf("%d \r\n&quo

  • C语言入门学习之fgets()函数和fputs()函数

    目录 fgets()函数 fputs()函数 总结 fgets()函数 fgets()函数和gets()函数一样,都是读取字符串,不过gets()函数通常用来从键盘读取输入的字符串,fgets()函数可以通过文件来读取字符串.下面通一个例子来演示fgets()函数的使用方法. int main() { FILE *in,*out; int ret; char ch; char str1[30],str2[30],str3[30]; /* 打开文件 */ in = fopen("123.txt&q

  • Go 语言入门学习之时间包

    目录 1.前言 2.日期和时间的表示 当前时间 日期函数 如何在Golang中获取当前UNIX的时间戳 3.访问时间组件的方法 1.前言 时间和日期对于任何编程语言来说都是一个非常重要的包. GO 语言 提供了 ​​time​​ 包来测量和显示时间.既可以根据所选时区获取当前时间,又可以使用 ​​time​​ 包添加当前时区的持续时间等. 2.日期和时间的表示 ​​time​​ 包提供了时间类型,用来表示时间中的一个特定时刻,主要有以下几个函数: Now() 函数:返回当前时区的当前时间 Dat

  • GO语言入门学习之基本数据类型字符串

    目录 字符串 字符串转义符 byte和rune类型 修改字符串 类型转换 总结 字符串 Go语言中的字符串以原生数据类型出现. Go 语言里的字符串的内部实现使用UTF-8编码. 字符串的值为双引号(")中的内容,可以在Go语言的源码中直接添加非ASCII码字符 GO语言中字符串是用双引号包裹的 GO语言中单引号包裹的是字符 // 字符串 s := "Hello 中国" // 单独的字母.汉字.符合表示一个字符 c1 := 'h' c2 := '1' c3 := '中' //

  • Go语言入门学习之Channel通道详解

    目录 前言 通道的声明 通道的初始化 发送和接收数据 通道的关闭 通道的容量与长度 缓冲通道与无缓冲通道 双向通道和单向通道 遍历通道 fibonacci 数列 参考文章: 总结 前言 不同于传统的多线程并发模型使用共享内存来实现线程间通信的方式,go 是通过 channel 进行协程 (goroutine) 之间的通信来实现数据共享. channel,就是一个管道,可以想像成 Go 协程之间通信的管道.它是一种队列式的数据结构,遵循先入先出的规则. 通道的声明 每个通道都只能传递一种数据类型的

  • C语言入门篇--学习选择,if,switch语句以及代码块

    目录 1.什么是语句 2.选择语句(分支语句) 2.1if语句&注意事项 2.1.1语法结构 2.1.2悬空else 2.2switch语句&注意事项 2.2.1语法结构 2.2.2switch语句中的break 2.2.3switch语句中的default语句 2.2.4switch语句的嵌套 3.代码块 1.什么是语句 语句:C语言中由一个 ; 隔开的就是一条语句. 例如: int a = 10; printf("haha\n"); 10; 'A'; ; //空语句

  • Flutter入门学习Dart语言变量及基本使用概念

    目录 正文 变量 变量的声明赋值 变量的划分 默认值 变量的类型推断修饰符 Late变量 类型判断is和类型转换as 一些重要概念 空安全和可空类型? 表达式和语句 注释 DartPad 正文 Dart是Google发布的开源编程语言,是一种面向对象的语言.其主要应用是Flutter框架开发(Android.IOS),此外,也可以用在服务器.脚本.Web开发中.随着Flutter3.0开始支持全平台开发,Dart也可以实现桌面应用. 关于Dart的介绍不再细说.下面开始Dart的使用介绍 首先记

  • C语言入门的一些基本资源推荐和程序语法概览

    为什么要学习C语言? 为什么要学习.使用C语言?为什么要学习一个可能比自己都岁数大的编程语言? 选择一门编程语言,"为什么而学"这个目的是最重要的,目的不明确就没法学好.这也是为什么很多学生朋友在大学里必修C语言却觉得没学明白的原因.因为学习的目的不明确,学习当然也没有动力.还有一个原因是C语言是工程实践性很强的语言,它不是来自某个研究所某个大学学院,而是实实在在从项目需要中产生,伴随着Unix的兴起而流行,语义简明清晰,功能强大而不臃肿,简洁而又不过分简单,实在是居家旅行工作学习必备

随机推荐