Golang正则表达式(regexp)Go内置了(regexp包)对正则表达式的⽀持,这⾥是⼀般的正则表达式常规⽤法的例⼦。
⽰例:
package main
import (
"bytes"
"fmt"
"regexp"
)
func main() {
//是否匹配字符串
// .匹配任意⼀个字符,*匹配零个或多个,优先匹配更多(贪婪)
match, _ := regexp.MatchString("H(.*)d!", "Hello World!")
fmt.Println(match) //true
//或
match, _ = regexp.Match("H(.*)d!", []byte("Hello World!"))
fmt.Println(match) //true
//或通过`Compile`来使⽤⼀个优化过的正则对象
r, _ := regexp.Compile("H(.*)d!")
fmt.Println(r.MatchString("Hello World!")) //true
// 这个⽅法返回匹配的⼦串
fmt.Println(r.FindString("Hello World! world")) //Hello World!
//同上
fmt.Println(string(r.Find([]byte("Hello World!")))) //Hello World!
// 这个⽅法查第⼀次匹配的索引
// 的起始索引和结束索引,⽽不是匹配的字符串
fmt.Println(r.FindStringIndex("Hello World! world")) //[0 12]
// 这个⽅法返回全局匹配的字符串和局部匹配的字符,匹配最⼤的⼦字符串⼀次。
// 它和r.FindAllStringSubmatch("Hello World! world",1) 等价。⽐如
// 这⾥会返回匹配`H(.*)d!`的字符串
// 和匹配`(.*)`的字符串
fmt.Println(r.FindStringSubmatch("Hello World! world")) //[Hello World! ello Worl]
// 和上⾯的⽅法⼀样,不同的是返回全局匹配和局部匹配的
// 起始索引和结束索引
fmt.Println(r.FindStringSubmatchIndex("Hello World! world")) //[0 12 1 10]
// 这个⽅法返回所有正则匹配的字符,不仅仅是第⼀个
fmt.Println(r.FindAllString("Hello World! Held! world", -1)) //[Hello World! Held!]
// 这个⽅法返回所有全局匹配和局部匹配的字符串起始索引,只匹配最⼤的串
// 和结束索引
fmt.Println(r.FindAllStringSubmatchIndex("Hello World! world", -1)) //[[0 12 1 10]]
fmt.Println(r.FindAllStringSubmatchIndex("Hello World! Held! world", -1)) //[[0 18 1 16]]
// 为这个⽅法提供⼀个正整数参数来限制匹配数量
res, _ := regexp.Compile("H([a-z]+)d!")
fmt.Println(res.FindAllString("Hello World! Held! Hellowrld! world", 2)) //[Held! Hellowrld!]
fmt.Println(r.FindAllString("Hello World! Held! world", 2)) //[Hello World! Held!]
/
/注意上⾯两个不同,第⼆参数是⼀最⼤⼦串为单位计算。
// regexp包也可以⽤来将字符串的⼀部分替换为其他的值
fmt.Println(r.ReplaceAllString("Hello World! Held! world", "html")) //html world
// `Func`变量可以让你将所有匹配的字符串都经过该函数处理
// 转变为所需要的值
in := []byte("Hello World! Held! world")
in := []byte("Hello World! Held! world")
out := r.ReplaceAllFunc(in, bytes.ToUpper)
fmt.Println(string(out))
// 在 b 中查 reg 中编译好的正则表达式,并返回第⼀个匹配的位置
// {起始位置, 结束位置}
b := bytes.NewReader([]byte("Hello World!"))
reg := regexp.MustCompile(`\w+`)
fmt.Println(reg.FindReaderIndex(b)) //[0 5]
// 在字符串中查 r 中编译好的正则表达式,并返回所有匹配的位置
// {{起始位置, 结束位置}, {起始位置, 结束位置}, ...}
// 只查前 n 个匹配项,如果 n < 0,则查所有匹配项
fmt.Println(r.FindAllIndex([]byte("Hello World!"), -1)) //[[0 12]]
//同上
fmt.Println(r.FindAllStringIndex("Hello World!", -1)) //[[0 12]]
// 在 s 中查 re 中编译好的正则表达式,并返回所有匹配的内容
// 同时返回⼦表达式匹配的内容
/
/ {
// {完整匹配项, ⼦匹配项, ⼦匹配项, ...},
// {完整匹配项, ⼦匹配项, ⼦匹配项, ...},
// ...
// }
// 只查前 n 个匹配项,如果 n < 0,则查所有匹配项
reg = regexp.MustCompile(`(\w)(\w)+`) //[[Hello H o] [World W d]]
fmt.Println(reg.FindAllStringSubmatch("Hello World!", -1)) //[[Hello H o] [World W d]]
// 将 template 的内容经过处理后,追加到 dst 的尾部。
// template 中要有 $1、$2、${name1}、${name2} 这样的“分组引⽤符”
// match 是由 FindSubmatchIndex ⽅法返回的结果,⾥⾯存放了各个分组的位置信息 // 如果 template 中有“分组引⽤符”,则以 match 为标准,
// 在 src 中取出相应的⼦串,替换掉 template 中的 $1、$2 等引⽤符号。
reg = regexp.MustCompile(`(\w+),(\w+)`)
src := []byte("Golang,World!") // 源⽂本
dst := []byte("Say: ") // ⽬标⽂本
template := []byte("Hello $1, Hello $2") // 模板
m := reg.FindSubmatchIndex(src) // 解析源⽂本
// 填写模板,并将模板追加到⽬标⽂本中
replaceall()fmt.Printf("%q", reg.Expand(dst, template, src, m))
// "Say: Hello Golang, Hello World"
// LiteralPrefix 返回所有匹配项都共同拥有的前缀(去除可变元素)
// prefix:共同拥有的前缀
/
/ complete:如果 prefix 就是正则表达式本⾝,则返回 true,否则返回 false
reg = regexp.MustCompile(`Hello[\w\s]+`)
fmt.Println(reg.LiteralPrefix())
// Hello false
reg = regexp.MustCompile(`Hello`)
fmt.Println(reg.LiteralPrefix())
// Hello true
text := `Hello World! hello world`
// 正则标记“⾮贪婪模式”(?U)
reg = regexp.MustCompile(`(?U)H[\w\s]+o`)
fmt.Printf("%q\n", reg.FindString(text)) // Hello
/
/ 切换到“贪婪模式”
reg.Longest()
fmt.Printf("%q\n", reg.FindString(text)) // Hello Wo
// 统计正则表达式中的分组个数(不包括“⾮捕获的分组”)
fmt.Println(r.NumSubexp()) //1
//返回 r 中的“正则表达式”字符串
fmt.Printf("%s\n", r.String())
fmt.Printf("%s\n", r.String())
// 在字符串中搜索匹配项,并以匹配项为分割符,将字符串分割成多个⼦串
// 最多分割出 n 个⼦串,第 n 个⼦串不再进⾏分割
// 如果 n < 0,则分割所有⼦串
/
/ 返回分割后的⼦串列表
fmt.Printf("%q\n", r.Split("Hello World! Helld! hello", -1)) //["" " hello"]
// 在字符串中搜索匹配项,并替换为 repl 指定的内容
// 如果 rep 中有“分组引⽤符”($1、$name),则将“分组引⽤符”当普通字符处理
// 全部替换,并返回替换后的结果
s := "Hello World, hello!"
reg = regexp.MustCompile(`(Hell|h)o`)
rep := "${1}"
fmt.Printf("%q\n", reg.ReplaceAllLiteralString(s, rep)) //"${1} World, hello!"
// 在字符串中搜索匹配项,然后将匹配的内容经过 repl 处理后,替换字符串中的匹配项 // 如果 repb 的返回值中有“分组引⽤符”($1、$name),则将“分组引⽤符”当普通字符处理 // 全部替换,并返回替换后的结果
ss := []byte("Hello World!")
reg = regexp.MustCompile("(H)ello")
repb := []byte("$0$1")
fmt.Printf("%s\n", reg.ReplaceAll(ss, repb))
// HelloH World!
fmt.Printf("%s\n", reg.ReplaceAllFunc(ss,
func(b []byte) []byte {
rst := []byte{}
rst = append(rst, b...)
rst = append(rst, "$1"...)
return rst
}))
// Hello$1 World!
}
⼩结:
1、
r, _ := regexp.Compile("H(.*)d!")
可⽤⼀下代替
r := regexp.MustCompile("H(.*)d!")
两者区别 MustCompile 少⼀个返回值err
看源码
// Compile parses a regular expression and returns, if successful,
/
/ a Regexp object that can be used to match against text.
//...
// For POSIX leftmost-longest matching, see CompilePOSIX.
func Compile(expr string) (*Regexp, error) {
return compile(expr, syntax.Perl, false)
}
// MustCompile is like Compile but panics if the expression cannot be parsed. // It simplifies safe initialization of global variables holding compiled regular
// expressions.
func MustCompile(str string) *Regexp {
regexp, err := Compile(str)
if err != nil {
panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
}
return regexp
}
2、regexp的处理byte的⽅法都有个string⽅法对应,两者功能⼀样。例如:
regexp.Match()
和
regexp.MatchString()
links
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论