regexp 标准库文档:https://studygolang.com/pkgdoc
func QuoteMeta(s string) string
例如,QuoteMeta('a.b')
会返回'a\.b'
。
func Match(pattern string, b []byte) (matched bool, err error)
func MatchString(pattern string, s string) (matched bool, err error)
func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)
这a个函数类似,一个匹配对象是二进制切片,一个匹配对象是字符串,一个匹配对象是 io.RuneReader
,使用举例:
matched, err := regexp.MatchString("foo.*", "seafood")
fmt.Println(matched, err)
matched, err = regexp.MatchString("bar.*", "seafood")
fmt.Println(matched, err)
matched, err = regexp.MatchString("a(b", "seafood")
fmt.Println(matched, err)
fmt.Println("--------------------------------------")
matched, err = regexp.Match("foo.*", []byte("seafood"))
fmt.Println(matched, err)
matched, err = regexp.Match("bar.*", []byte("seafood"))
fmt.Println(matched, err)
matched, err = regexp.Match("a(b", []byte("seafood"))
fmt.Println(matched, err)
fmt.Println("--------------------------------------")
f, err := os.Open("/home/hongyu/go/src/test/regexp/matchreader.txt")
if err != nil {
fmt.Println("open file err", err)
}
rr := bufio.NewReader(f)
defer f.Close()
matched, err = regexp.MatchReader("foo.*", rr)
fmt.Println(matched, err)
matched, err = regexp.MatchReader("bar.*", rr)
fmt.Println(matched, err)
matched, err = regexp.MatchReader("a(b", rr)
fmt.Println(matched, err)
/* 输出
true
false
false error parsing regexp: missing closing ): `a(b`
*/
type Regexp struct {
// 内含隐藏或非导出字段
}
Regexp
表示一个编译好的正则表达式
func Compile(expr string) (*Regexp, error)
Compile
用来解析正则表达式 expr
是否合法,如果合法,则返回一个 Regexp 对象
func CompilePOSIX(expr string) (*Regexp, error)
CompilePOSIX
的作用和 Compile
一样, 不同的是,CompilePOSIX
使用 POSIX
语法,同时,它采用最左最长方式搜索,而 Compile
采用最左最短方式搜索.
func MustCompile(str string) *Regexp
MustCompile
类似 Compile
但会在解析失败时 panic
,主要用于全局正则表达式变量的安全初始化。
func MustCompilePOSIX(str string) *Regexp
MustCompilePOSIX
类似 CompilePOSIX
但会在解析失败时 panic
,主要用于全局正则表达式变量的安全初始化。
func (re *Regexp) String() string
返回 正则表达式字符串
func (re *Regexp) LiteralPrefix() (prefix string, complete bool)
返回所有匹配项都共同拥有的前缀(去除可变元素)
func main() {
reg := regexp.MustCompile(`Hello[\w\s]+`)
fmt.Println(reg.LiteralPrefix()) // Hello false
reg = regexp.MustCompile(`Hello`)
fmt.Println(reg.LiteralPrefix()) // Hello true
}
func (re *Regexp) NumSubexp() int
NumSubexp
返回该正则表达式中捕获分组的数量。
func main() {
reg := regexp.MustCompile(`(?U)(?:Hello)(\s+)(\w+)`)
fmt.Println(reg.NumSubexp()) // 2
}
func (re *Regexp) SubexpNames() []string
返回 re 中的分组名称列表,未命名的分组返回空字符串
func main() {
re := regexp.MustCompile("(?PHello)(World)" )
fmt.Printf("%q\n", re.SubexpNames()) // ["" "Hello" ""]
}
func (re *Regexp) Longest()
Longest
让正则表达式在之后的搜索中都采用 “贪婪” 模式,切换为 贪婪模式。(默认就是贪婪模式)
func main() {
text := `Hello World, 123 Go!`
pattern := `(?U)H[\w\s]+o` // 正则标记“非贪婪模式”(?U)
reg := regexp.MustCompile(pattern)
fmt.Printf("%q\n", reg.FindString(text)) // Hello
reg.Longest() // 切换到“贪婪模式”
fmt.Printf("%q\n", reg.FindString(text)) // Hello Wo
}
func (re *Regexp) Match(b []byte) bool
Match
检查 b 中是否存在匹配 pattern
的子序列。
text = `Hello World, 123 Go!`
pattern = `H[\w\s]`
reg = regexp.MustCompile(pattern)
fmt.Println(reg.Match([]byte(text))) // true
func (re *Regexp) MatchString(s string) bool
同 Match()
func (re *Regexp) MatchReader(r io.RuneReader) bool
MatchReader
类似Match
,但匹配对象是 io.RuneReader
。
func (re *Regexp) Find(b []byte) []byte
Find返回保管正则表达式re在b中的最左侧的一个匹配结果的[]byte切片。如果没有匹配到,会返回nil。
reg = regexp.MustCompile(`\w+ `)
fmt.Printf("%q\n", reg.Find([]byte("Hello World!"))) // "Hello "
func (re *Regexp) FindString(s string) string
Find
返回保管正则表达式 re
在 s
中的最左侧的一个匹配结果的字符串。如果没有匹配到,会返回"";但如果正则表达式成功匹配了一个空字符串,也会返回 “”。如果需要区分这种情况,请使用 FindStringIndex
或 FindStringSubmatch
。
re := regexp.MustCompile("fo.?")
fmt.Printf("%q\n", re.FindString("seafood")) // "foo"
fmt.Printf("%q\n", re.FindString("meat")) // ""
func (re *Regexp) FindIndex(b []byte) (loc []int)
返回 b byte切片左侧第一处与正则表达式 re 相匹配的子切片所在的起止索引位置,如果没有匹配到,返回 [] 空切片:
re = regexp.MustCompile("fo.?")
fmt.Println(re.FindIndex([]byte("seafoodfood"))) // [3, 6]
fmt.Println(re.FindIndex([]byte("meat"))) // []
func (re *Regexp) FindStringIndex(s string) (loc []int)
同 FindIndex
,不同的是匹配对象是 字符串类型。
func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int)
同 FindIndex
,不同的是匹配对象是 io.RunReader
接口类型。
re = regexp.MustCompile("fo.?")
f, err = os.Open("/home/hongyu/go/src/test/regexp/matchreader.txt")
if err != nil {
fmt.Println("open file err", err)
}
fmt.Println(re.FindReaderIndex(bufio.NewReader(f)))
f.Close()
func (re *Regexp) FindSubmatch(b []byte) [][]byte
在 b 中查找 re 中编译好的正则表达式,并返回第一个匹配的内容, 同时返回(可能有的)分组匹配的结果的 [][]byte
切片(子组)。
re = regexp.MustCompile(`(\w)(\w)+`)
fmt.Printf("%q\n", re.FindSubmatch([]byte("Hello World!"))) // ["Hello" "H" "o"]
func (re *Regexp) FindStringSubmatch(s string) []string
同 FindSubmatch
func (re *Regexp) FindSubmatchIndex(b []byte) []int
功能类似于 FindSubmatch
, 不同的地方是返回的是匹配的子切片的索引:
re = regexp.MustCompile(`(\w)(\w)+`)
fmt.Println(re.FindSubmatchIndex([]byte("Hello World!"))) # [0 5 0 1 4 5], 0~5-1 == Hello, 0~1-1 == H, 4~5-1 == o
func (re *Regexp) FindStringSubmatchIndex(s string) []int
同 FindSubmatchIndex
func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int
同 FindSubmatchIndex
。
func (re *Regexp) FindAll(b []byte, n int) [][]byte
返回 b 中所有与 正则表达式 re 相匹配的内容, 返回 [][]byte
, 只查找前 n
个匹配项,如果 n < 0
,则查找所有匹配项.
reg = regexp.MustCompile("a.c")
fmt.Printf("%q\n", reg.FindAll([]byte("abc azc a7c aac 888 a9c tac"), -1)) // ["abc" "azc" "a7c" "aac" "a9c"]
fmt.Printf("%q\n", reg.FindAll([]byte("abc azc a7c aac 888 a9c tac"), 2)) // ["abc" "azc"]
func (re *Regexp) FindAllString(s string, n int) []string
同 FindALl
func (re *Regexp) FindAllIndex(b []byte, n int) [][]int
b
中的所有不重叠的、与 正则表达式 相匹配的结果的 起止位置的切片,只查找前 n
个匹配项,如果 n < 0
,则查找所有匹配项.
reg = regexp.MustCompile("a.c")
fmt.Println(reg.FindAllIndex([]byte("abc azc a7c aac 888 a9c tac"), 2)) // [[0 3] [4 7]]
func (re *Regexp) FindAllStringIndex(s string, n int) [][]int
同 FindAllIndex
func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte
类似 FindSubmatch
方法, FindSubmatch
是返回匹配的第一个的字符串 及 与子组匹配的字符串,只查找前 n
个匹配项,如果 n < 0
,则查找所有匹配项.:
reg = regexp.MustCompile(`(a.c)([\w]+)`)
fmt.Printf("%q\n", reg.FindAllSubmatch([]byte("abce azcea a7cx"), 2)) // [["abce" "abc" "e"] ["azcea" "azc" "ea"]]
func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
同 FindAllSubmatch
func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int
在 b 中查找 re 中编译好的正则表达式,并返回所有匹配的位置, 同时返回子表达式匹配的位置 ,只查找前 n
个匹配项,如果 n < 0
,则查找所有匹配项.
reg = regexp.MustCompile(`(a.c)([\w]+)`)// [[完整项起始, 完整项结束, 子项起始, 子项结束, 子项起始, 子项结束, ...], ]
fmt.Println( reg.FindAllSubmatchIndex([]byte("abce azcea a7cx"), 2)) // [[0 4 0 3 3 4] [5 10 5 8 8 10]]
func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int
同 FindAllSubmatchIndex
func (re *Regexp) Split(s string, n int) []string
Split
将 re
在 s
中匹配到的结果作为分隔符将 s
分割成多个字符串,并返回这些正则匹配结果之间的字符串的切片。 `
返回的切片不会包含正则匹配的结果
txt := "abcxxefgxxhijkxxlmnxx"
reg = regexp.MustCompile("xx")
fmt.Printf("%q\n", reg.Split(txt, -1)) // ["abc" "efg" "hijk" "lmn" ""]
func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte
将 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") // 模板
match := reg.FindSubmatchIndex(src) // 解析源文本
fmt.Printf("%q\n", reg.Expand(dst, template, src, match)) // 填充模板,并将模板追加到目标文本中
// "Say: Hello Golang, Hello World"
正则可以写为: (?P
, 然后模板应该为:Hello $n1, Hello $n2
func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte
同 Expand
func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte
在 src 中搜索匹配项,并替换为 repl 指定的内容,并返回替换后的结果.
如果 repl
中有 “分组引用符”($1
、$name
),则将“分组引用符”当普通字符处理.
b := []byte("Hello World, 123 Go!")
reg = regexp.MustCompile(`(Hell|G)o`)
rep := []byte("${1}ooo")
fmt.Printf("%q\n", reg.ReplaceAllLiteral(b, rep)) // "${1}ooo World, 123 ${1}ooo!"
func (re *Regexp) ReplaceAllLiteralString(src, repl string) string
同 ReplaceAllLiteral
func (re *Regexp) ReplaceAll(src, repl []byte) []byte
在 src
中搜索匹配项,并替换为 repl
指定的内容, 全部替换,并返回替换后的结果.
如果 repl
中有 “分组引用符”($1
、$name
),则将“分组引用符”替换为匹配到的相应的分组(会按照 Expand
方法的规则进行解释和替换).
b := []byte("Hello World, 123 Go!")
reg := regexp.MustCompile(`(Hell|G)o`)
rep := []byte("${1}ooo")
fmt.Printf("%q\n", reg.ReplaceAll(b, rep)) // "Hellooo World, 123 Gooo!"
func (re *Regexp) ReplaceAllString(src, repl string) string
同 ReplaceAll
func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
在 src
中搜索匹配项,然后将匹配的内容作为 repl
的参数处理后,替换 src
中的匹配项;
如果 repl
的返回值中有“分组引用符”($1
、$name
),则将“分组引用符”当普通字符处理;
s := []byte("Hello World!")
reg := regexp.MustCompile("(H)ello")
fmt.Printf("%s\n", reg.ReplaceAllFunc(s, func(b []byte) []byte {
rst := []byte{}
rst = append(rst, b...)
rst = append(rst, []byte("$1")...)
return rst
}))
func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string
同 ReplaceAllFunc