# 基本的字符串是否存在检测
func main() {
// a 和 b 中间
matched, _ := regexp.MatchString(`a.b`, "aawbb")
fmt.Println(matched) // true
// 使用 ? 匹配 0 次或者 1 次
matched, _ = regexp.MatchString(`a.?b`, "awb")
fmt.Println(matched) // true
// a 和 b 中间是数字
matched, _ = regexp.MatchString(`a([0-9]+)b`, "a123b")
fmt.Println(matched) // true
// 使用了 + 匹配一次或者无限次
matched, _ = regexp.MatchString(`^a.+b$`, "aawxxxbb")
fmt.Println(matched) // true
// 首尾限定
matched, _ = regexp.MatchString(`^a.b$`, "awb")
fmt.Println(matched) // true
// 首尾限定并且 a 和 b 中间可以最多 1 个字符
matched, _ = regexp.MatchString(`^a.?b$`, "awb")
fmt.Println(matched) // true
第一个例子使用了点 . 符号,表示匹配任意字符,可以匹配 a 和 b 中间的任意一个字符。
第二个例子使用了问号 ? 符号,表示匹配前一个字符 0 次或者 1 次,因此可以匹配 a 和 b 中间没有字符或只有一个字符的情况。
第三个例子使用了中括号 [] 和加号 + 符号,表示匹配一个或多个数字。因此可以匹配 a 和 b 中间是一串数字的情况。
第四个例子使用了加号 + 符号,表示匹配前一个字符 1 次或多次,可以匹配 a 和 b 中间有多个字符的情况。
第五个例子使用了 ^ 和 $ 符号,表示限定匹配的字符串以 a 开头,以 b 结尾,中间是任意一个字符。
第六个例子在第五个例子的基础上使用了问号 ? 符号,表示匹配前一个字符 0 次或者 1 次,因此可以匹配 a 和 b 中间没有字符或只有一个字符的情况。
# 查找字符串
func main() {
re := regexp.MustCompile(`foo.?`)
fmt.Printf("%q\n", re.FindString("seafood fool")) // "food"
fmt.Printf("%d\n", re.FindStringIndex("seafood fool")) // [3 7]
re = regexp.MustCompile(`foo.*`)
fmt.Printf("%q\n", re.FindString("seafood fool")) // "food fool"
fmt.Printf("%d\n", re.FindStringIndex("seafood fool")) // [3 12]
re = regexp.MustCompile(`foo.+`)
fmt.Printf("%q\n", re.FindString("seafood fool")) // "food fool"
fmt.Printf("%d\n", re.FindStringIndex("seafood fool")) // [3 12]
fmt.Printf("%q\n", re.FindString("meat")) // ""
fmt.Printf("%d\n", re.FindStringIndex("meat")) // []
首先,使用 Regexp.MustCompile 函数编译了一个正则表达式 foo.?,然后调用 FindString 方法查找匹配的字符串,找到第一个匹配项 "food",输出结果为 "food",同时调用 FindStringIndex 方法也可以找到匹配项的起始和结束位置,输出结果为 [3 7]。
接下来,使用 Regexp.MustCompile 函数编译了一个正则表达式 foo.*,它使用了通配符 * 匹配前面的字符零次或多次,因此可以匹配到 "food" 和 "fool",输出结果为 "food fool",同时调用 FindStringIndex 方法也可以找到匹配项的起始和结束位置,输出结果为 [3 12]。
然后,使用 Regexp.MustCompile 函数编译了一个正则表达式 foo.+,它使用了通配符 + 匹配前面的字符一次或多次,因此可以匹配到 "food" 和 "fool",输出结果为 "food fool",同时调用 FindStringIndex 方法也可以找到匹配项的起始和结束位置,输出结果为 [3 12]。
最后,调用 FindString 和 FindStringIndex 方法查找字符串 "meat",由于该字符串没有匹配项,输出结果分别为 "" 和 []。
# 查找所有的匹配
func main() {
re := regexp.MustCompile(`a.`)
fmt.Printf("%q\n", re.FindAllString("paranormal", -1)) // ["ar" "an" "al"]
fmt.Printf("%q\n", re.FindAllString("paranormal", 2)) // ["ar" "an"]
fmt.Printf("%q\n", re.FindAllString("graal", -1)) // ["aa"]
fmt.Printf("%q\n", re.FindAllString("none", -1)) // []
代码首先通过 regexp.MustCompile 方法编译了一个正则表达式 a.,它表示一个字母 a 后面紧跟着任意一个字符。然后,它分别将字符串 "paranormal"、"graal" 和 "none" 作为参数传给 FindAllString 方法,并分别打印出返回的结果。
对于字符串 "paranormal",正则表达式 a. 匹配了三个子字符串 "ar"、"an" 和 "al",所以 FindAllString 返回了一个由这三个字符串组成的切片。由于第二个参数是 -1,所以返回所有匹配结果。
对于字符串 "graal",正则表达式 a. 只匹配了一个子字符串 "aa",所以 FindAllString 返回了一个只含有一个元素 "aa" 的切片。
对于字符串 "none",正则表达式 a. 没有匹配到任何子字符串,所以 FindAllString 返回了一个空的切片。
最后一个参数是限制返回匹配次数的参数。当这个参数大于 0 时,FindAllString 方法最多只返回给定数量的匹配结果。当这个参数为 0 或负数时,FindAllString 方法返回所有匹配结果。在这个例子中,第二个 FindAllString 方法将最多返回两个匹配结果。
# 替换匹配的字符串
func main() {
re := regexp.MustCompile(`ab*`)
fmt.Printf("%q\n", re.ReplaceAllString("-a-abb-", "T")) // "-T-T-"
re = regexp.MustCompile(`ab?`)
fmt.Printf("%q\n", re.ReplaceAllString("-a-abb-", "T")) // "-T-Tb-"
re = regexp.MustCompile(`ab+`)
fmt.Printf("%q\n", re.ReplaceAllString("-a-abb-", "T")) // "-a-T-"
第一个正则表达式 ab* 匹配字符 a 后面跟着零个或多个 b。因此,它将 -a-abb- 中的 -a- 替换为 T,并将 -abb- 替换为 T,最终得到字符串 -T-T-。
第二个正则表达式 ab? 匹配字符 a 后面跟着零个或一个 b。因此,它将 -a-abb- 中的 -a- 替换为 T,并将 -ab- 替换为 T,但不替换 -b-。最终得到字符串 -T-Tb-。
第三个正则表达式 ab+ 匹配字符 a 后面跟着至少一个 b。因此,它将 -a-abb- 中的 -abb- 替换为 T,但不替换 -a- 或 -b-。最终得到字符串 -a-T-。
# 用匹配位置分割
func main() {
ra := regexp.MustCompile(`a`)
fmt.Printf("%q\n", ra.Split("banana", -1)) // ["b" "n" "n" ""]
fmt.Printf("%q\n", ra.Split("banana", 0)) // []
fmt.Printf("%q\n", ra.Split("banana", 1)) // ["banana"]
fmt.Printf("%q\n", ra.Split("banana", 2)) // ["b" "nana"]
rz := regexp.MustCompile(`z+`)
fmt.Printf("%q\n", rz.Split("pizza", -1)) // ["pi" "a"]
fmt.Printf("%q\n", rz.Split("pizza", 0)) // []
fmt.Printf("%q\n", rz.Split("pizza", 1)) // ["pizza"]