1. Golang中的正则表达式包
Golang提供了内置的regexp包
,用于处理正则表达式操作。该包提供正则表达式对象,可以执行各种文本操作,如匹配、查找和替换。
Golang中的regexp包
提供了一组函数和类型,用于处理正则表达式。以下是一些常用的函数:
- regexp.Compile : 编译正则表达式,返回正则对象。
- regexp.Match : 判断文本是否与正则表达式匹配。
- regexp.FindString : 查找并返回第一个匹配的字符串。
- regexp.FindAllString : 查找并返回所有匹配的字符串。
- regexp.ReplaceAllString : 替换所有匹配的字符串。
2. 正则表达式语法简述
在使用正则表达式时,了解其语法规则至关重要。以下是一些常用的正则表达式元字符及其含义:
.
: 匹配任意字符,除了换行符。*
: 匹配前一个字符零次或多次。+
: 匹配前一个字符一次或多次。?
: 匹配前一个字符零次或一次。\d
: 匹配数字字符。\w
: 匹配字母、数字或下划线。[]
: 字符集,匹配括号内的任意一个字符。
3. 相关示例
邮箱匹配
package main
import (
"fmt"
"regexp"
)
func main() {
text := "邮箱是 demo@qq.com 。"
re := regexp.MustCompile(`[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}`)
matches := re.FindStringSubmatch(text)
if len(matches) > 0 {
fmt.Println("匹配的邮箱地址:", matches[0])
}
}
匹配 URL
text := "这是一个链接文本:https://www.163.com 和 https://www.google.com"
re := regexp.MustCompile(`https?://[^\s]+`)
matches := re.FindAllString(text, -1)
for _, match := range matches {
fmt.Println("匹配的链接:", match)
}
数字、汉字、拼音的匹配
reg1 := regexp.MustCompile(`[0-9]+`) //正则 匹配数字
reg2 := regexp.MustCompile(`[\p{Han}]+`) //正则 匹配汉字
reg3 := regexp.MustCompile(`[a-z]+`) //正则 匹配拼音
通过 Find 匹配(传入[]byte,返回[]byte)
//----------- Find 使用 -----------------//
str := "ab001234hah120210a880218end"
reg := regexp.MustCompile("\\d{6}") //六位连续的数字
// 返回str中第一个匹配reg的字符串
data := reg.Find([]byte(str))
fmt.Println(string(data))
//----------- FindAll 使用 ---------------//
//返回 str中所有匹配reg的字符串, 第二个参数表示最多返回的个数,传-1表示返回所有结果
dataSlice := reg.FindAll([]byte(str), -1)
for _, v := range dataSlice {
fmt.Println(string(v))
}
FindIndex 获取索引位
//------------- FindIndex ----------------//
str := "00start123endhahastart120PSend09start10000end"
// 返回第一个匹配的字符串的首末位置
reg := regexp.MustCompile("start\\d*end") //start开始,end结束,中间全是数字
// index[0]表示开始位置,index[1]表示结束位置
index := reg.FindIndex([]byte(str))
fmt.Println("start:", index[0], ",end:", index[1], str[index[0]:index[1]])
//------------- FindAllIndex ----------------//
// 返回所有匹配的字符串首末位置
indexSlice := reg.FindAllIndex([]byte(str), -1)
for _, v := range indexSlice {
fmt.Println("start:", v[0], ",end:", v[1], str[v[0]:v[1]])
}
FindString 操作更方便
//-----------FindString 和 FindAllString ----------------//
str := "ab001234hah120210a880218end"
reg := regexp.MustCompile("\\d{6}") //六位连续的数字
fmt.Println(reg.FindString(str))
fmt.Println(reg.FindAllString(str, -1))
// 以下两个方法是类似的,获取索引位
fmt.Println(reg.FindStringIndex(str))
fmt.Println(reg.FindIndex([]byte(str)))
// 查找汉字
str1 := "hello中国hello世界和平hi好"
reg1 := regexp.MustCompile("[\\p{Han}]+")
fmt.Println(reg1.FindAllString(str1, -1)) // [中国 世界和平 好]
// 查找数字或小写字母
str2 := "HAHA00azBAPabc09FGabHY99"
reg2 := regexp.MustCompile("[\\d|a-z]+")
fmt.Println(reg2.FindAllString(str2, -1)) // [00az abc09 ab 99]
//----------- ReplaceAllString ----------------//
// 查找并替换
str3 := "Welcome for Beijing-Tianjin CRH train"
reg3 := regexp.MustCompile(" ")
fmt.Println(reg.ReplaceAllString(str3, "@")) //将空格替换为@字符
// Welcome@for@Beijing-Tianjin@CRH@train
常用匹配
text := `Hello 世界!123 Go.`
// 查找连续的小写字母
reg := regexp.MustCompile(`[a-z]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1) // 输出结果["ello" "o"]
// 查找连续的非小写字母
reg = regexp.MustCompile(`[^a-z]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["H" " 世界!123 G" "."]
// 查找连续的单词字母
reg = regexp.MustCompile(`[\w]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "123" "Go"]
// 查找连续的非单词字母、非空白字符
reg = regexp.MustCompile(`[^\w\s]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["世界!" "."]
// 查找连续的大写字母
reg = regexp.MustCompile(`[[:upper:]]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["H" "G"]
// 查找连续的非 ASCII 字符
reg = regexp.MustCompile(`[[:^ascii:]]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["世界!"]
// 查找连续的标点符号
reg = regexp.MustCompile(`[\pP]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["!" "."]
// 查找连续的非标点符号字符
reg = regexp.MustCompile(`[\PP]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello 世界" "123 Go"]
// 查找连续的汉字
reg = regexp.MustCompile(`[\p{Han}]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["世界"]
// 查找连续的非汉字字符
reg = regexp.MustCompile(`[\P{Han}]+`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello " "!123 Go."]
// 查找 Hello 或 Go
reg = regexp.MustCompile(`Hello|Go`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "Go"]
// 查找行首以 H 开头,以空格结尾的字符串
reg = regexp.MustCompile(`^H.*\s`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello 世界!123 "]
// 查找行首以 H 开头,以空白结尾的字符串(非贪婪模式)
reg = regexp.MustCompile(`(?U)^H.*\s`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello "]
// 查找以 hello 开头(忽略大小写),以 Go 结尾的字符串
reg = regexp.MustCompile(`(?i:^hello).*Go`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello 世界!123 Go"]
// 查找 Go.
reg = regexp.MustCompile(`\QGo.\E`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Go."]
// 查找从行首开始,以空格结尾的字符串(非贪婪模式)
reg = regexp.MustCompile(`(?U)^.* `)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello "]
// 查找以空格开头,到行尾结束,中间不包含空格字符串
reg = regexp.MustCompile(` [^ ]*$`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // [" Go."]
// 查找“单词边界”之间的字符串
reg = regexp.MustCompile(`(?U)\b.+\b`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" " 世界!" "123" " " "Go"]
// 查找连续 1 次到 4 次的非空格字符,并以 o 结尾的字符串
reg = regexp.MustCompile(`[^ ]{1,4}o`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "Go"]
// 查找 Hello 或 Go
reg = regexp.MustCompile(`(?:Hell|G)o`)
fmt.Printf("%q\n", reg.FindAllString(text, -1)) // ["Hello" "Go"]
// 查找 Hello 或 Go,替换为 Hellooo、Gooo
reg = regexp.MustCompile(`(?PHell|G)o`)
fmt.Printf("%q\n", reg.ReplaceAllString(text, "${n}ooo")) // "Hellooo 世界!123 Gooo."
// 交换 Hello 和 Go
reg = regexp.MustCompile(`(Hello)(.*)(Go)`)
fmt.Printf("%q\n", reg.ReplaceAllString(text, "$3$2$1")) // "Go 世界!123 Hello."
reg = regexp.MustCompile(`[\f\t\n\r\v\123\x7F\x{10FFFF}\\\^\$\.\*\+\?\{\}\(\)\[\]\|]`)
fmt.Printf("%q\n", reg.ReplaceAllString("\f\t\n\r\v\123\x7F\U0010FFFF\\^$.*+?{}()[]|", "-"))
4. 总结
在Golang中,使用regexp包
可以轻松实现各种文本操作。无论是从文本中提取信息还是进行验证,正则表达式都是编程中不可或缺的一部分。