golang 正则匹配regexp接口实战学习

作者: kingeasternsun | 来源:发表于2017-07-12 10:01 被阅读0次

    总览

    如果不熟悉正则表达式的语法的话,可以执行下面命令:

    go doc regexp/syntax
    

    联系代码

    package main
    
    import (
        "fmt"
        "regexp"
    )
    
    func expandTest() {
        pat := `(((abc.)def.)ghi)`
        reg := regexp.MustCompile(pat)
        fmt.Println(reg.NumSubexp())
    
        src := []byte(`abc-def-ghi abc+def+ghi`)
        template := []byte(`$0   $1   $2   $3`)
    
        // 替换第一次匹配结果
        match := reg.FindSubmatchIndex(src)
        fmt.Printf("%v\n", match) // [0 11 0 11 0 8 0 4]
        dst := reg.Expand(nil, template, src, match)
        fmt.Printf("%s\n\n", dst)
        // abc-def-ghi   abc-def-ghi   abc-def-   abc-
    
        // 替换所有匹配结果
        for _, match := range reg.FindAllSubmatchIndex(src, -1) {
            fmt.Printf("%v\n", match)
            dst := reg.Expand(nil, template, src, match)
            fmt.Printf("%s\n", dst)
        }
        // [0 11 0 11 0 8 0 4]
        // abc-def-ghi   abc-def-ghi   abc-def-   abc-
        // [12 23 12 23 12 20 12 16]
        // abc+def+ghi   abc+def+ghi   abc+def+   abc+
    }
    
    func testFind() {
        re := regexp.MustCompile("a*r")
        fmt.Println(string(re.Find([]byte("paranoabrmal"))))
        fmt.Println(re.NumSubexp())
    
        rep := regexp.MustCompilePOSIX("a*r|ara")
        fmt.Println(string(rep.Find([]byte("paranoabrmal"))))
        fmt.Println(rep.NumSubexp())
    
        b := []byte("abc1def1")
        pat := `abc1|abc1def1`
        reg1 := regexp.MustCompile(pat)      // 第一匹配
        reg2 := regexp.MustCompilePOSIX(pat) // 最长匹配
        fmt.Printf("%s\n", reg1.Find(b))     // abc1
        fmt.Printf("%s\n", reg2.Find(b))     // abc1def1
        fmt.Println(reg1.NumSubexp())
    
        b = []byte("abc1def1")
        pat = `(abc|abc1def)*1`
        reg1 = regexp.MustCompile(pat)      // 第一匹配
        reg2 = regexp.MustCompilePOSIX(pat) // 最长匹配
        fmt.Printf("%s\n", reg1.Find(b))    // abc1
        fmt.Printf("%s\n", reg2.Find(b))    // abc1def1
        fmt.Println(reg1.NumSubexp())
    }
    
    func testFindAll() {
        re := regexp.MustCompile("ar")
        fmt.Printf("%q\n", (re.FindAll([]byte("paranoarmal"), -1)))
    
        rep := regexp.MustCompilePOSIX("ar")
        fmt.Printf("%q\n", (rep.FindAll([]byte("paranoarmal"), -1)))
    
        pat := `(((abc.)def.)ghi)`
        src := []byte(`abc-def-ghi abc+def+ghi`)
    
        reg := regexp.MustCompile(pat)
        fmt.Printf("%q\n", (reg.Find(src)))
        fmt.Printf("%q\n", (reg.FindAll(src, -1)))
        regp := regexp.MustCompilePOSIX(pat)
        fmt.Printf("%q\n", (regp.Find(src)))
        fmt.Printf("%q\n", (regp.FindAll(src, -1)))
    
    }
    
    func testReg(pat, srcStr string) {
    
        fmt.Println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
        src := []byte(srcStr)
    
        reg := regexp.MustCompile(pat)
        fmt.Printf("%q\n", (reg.Find(src)))
        fmt.Printf("%q\n", (reg.FindString(srcStr)))
    
        fmt.Printf("%q\n", (reg.FindAll(src, -1)))
        fmt.Printf("%q\n", (reg.FindAllString(srcStr, -1)))
    
        fmt.Printf("%d\n", (reg.FindIndex(src)))
        fmt.Printf("%d\n", (reg.FindStringIndex(srcStr)))
    
        fmt.Printf("%d\n", (reg.FindAllIndex(src, -1)))
        fmt.Printf("%d\n", (reg.FindAllStringIndex(srcStr, -1)))
    
        fmt.Println("begin submatch")
        fmt.Printf("%q\n", (reg.FindSubmatch(src)))
        fmt.Printf("%q\n", (reg.FindStringSubmatch(srcStr)))
    
        fmt.Printf("%d\n", (reg.FindSubmatchIndex(src)))
        fmt.Printf("%d\n", (reg.FindStringSubmatchIndex(srcStr)))
    
        fmt.Printf("%q\n", (reg.FindAllSubmatch(src, -1)))
        fmt.Printf("%q\n", (reg.FindAllStringSubmatch(srcStr, -1)))
    
        fmt.Printf("%d\n", (reg.FindAllSubmatchIndex(src, -1)))
        fmt.Printf("%d\n", (reg.FindAllStringSubmatchIndex(srcStr, -1)))
    
        regp := regexp.MustCompilePOSIX(pat)
        fmt.Printf("%q\n", (regp.Find(src)))
        fmt.Printf("%q\n", (regp.FindString(srcStr)))
    
        fmt.Printf("%q\n", (regp.FindAll(src, -1)))
        fmt.Printf("%q\n", (regp.FindAllString(srcStr, -1)))
    
        fmt.Printf("%d\n", (regp.FindIndex(src)))
        fmt.Printf("%d\n", (regp.FindStringIndex(srcStr)))
    
        fmt.Printf("%d\n", (regp.FindAllIndex(src, -1)))
        fmt.Printf("%d\n", (regp.FindAllStringIndex(srcStr, -1)))
    
        fmt.Println("begin submatch")
        fmt.Printf("%q\n", (regp.FindSubmatch(src)))
        fmt.Printf("%q\n", (regp.FindStringSubmatch(srcStr)))
    
        fmt.Printf("%q\n", (regp.FindAllSubmatch(src, -1)))
        fmt.Printf("%q\n", (regp.FindAllStringSubmatch(srcStr, -1)))
    
        fmt.Printf("%d\n", (regp.FindSubmatchIndex(src)))
        fmt.Printf("%d\n", (regp.FindStringSubmatchIndex(srcStr)))
    
        fmt.Printf("%d\n", (regp.FindAllSubmatchIndex(src, -1)))
        fmt.Printf("%d\n", (regp.FindAllStringSubmatchIndex(srcStr, -1)))
    
    }
    
    func main() {
    
        testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
        testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
        testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
        testReg(`a*r`, `paranoabrmal`)
    
    }
    
    

    代码详解

    Find FindString

    fmt.Printf("%q\n", (reg.Find(src)))
    fmt.Printf("%q\n", (reg.FindString(srcStr)))
    

    Find返回leftmost的正则匹配结果,也就是满足匹配的最左边的最短匹配字符串

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:"abc-def-ghixx"
    分析:*表示0或多个,优先选择多个,所以优先匹配为"abc-def-ghixx"
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:"abc-def-ghi"
    分析:满足匹配项的的最左的最短匹配就是"abc-def-ghi"
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:"axxxbyc"
    分析:满足匹配项的的最左的最短匹配就是"abc-def-ghi"
    
    testReg(`a*r`, `paranoabrmal`)
    结果:"ar"
    分析:满足匹配项的的最左的最短匹配就是"ar"
    

    FindAll FIndAllString

    fmt.Printf("%q\n", (reg.FindAll(src, -1)))
    fmt.Printf("%q\n", (reg.FindAllString(srcStr, -1)))
    

    FindAll是Find的“ALL”版本,返回相邻的非互相覆盖的最短匹配项

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:["abc-def-ghixx" "abc+def+ghixx"]
    分析:返回所有匹配项
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:["abc-def-ghi" "abc+def+ghi"]
    分析:返回所有匹配项
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:["axxxbyc" "abzc"]
    分析:返回所有匹配项
    
    testReg(`a*r`, `paranoabrmal`)
    结果:["ar" "r"]
    分析:*表示0或多个,所以第二个就仅仅匹配了r
    

    FindIndex FindStringIndex

    fmt.Printf("%d\n", (reg.FindIndex(src)))
    fmt.Printf("%d\n", (reg.FindStringIndex(srcStr)))
    

    FindIndex是Find的“Index”版本,匹配项在原字符串中的位置,返回nil标示没有找到匹配项。

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[0 13]
    分析:`abc-def-ghixxa abc+def+ghixx`[0:13]就是"abc-def-ghixx"
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[0 11]
    分析:同上
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:[1 8]
    分析:同上
    
    testReg(`a*r`, `paranoabrmal`)
    结果:[1 3]
    分析:同上
    

    FindAllIndex FindAllStringIndex

    fmt.Printf("%d\n", (reg.FindAllIndex(src, -1)))
    fmt.Printf("%d\n", (reg.FindAllStringIndex(srcStr, -1)))
    

    FindAllIndex是FindAll的“Index”版本,标示匹配项在原字符串中的位置,返回nil标示没有找到匹配项。

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[[0 13] [15 28]]
    分析:`abc-def-ghixxa abc+def+ghixx`[0:13]就是"abc-def-ghixx"
            `abc-def-ghixxa abc+def+ghixx`[15:28]就是"abc+def+ghixx"
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[[0 11] [15 26]]
    分析:同上
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:[[1 8] [11 15]]
    分析:同上
    
    testReg(`a*r`, `paranoabrmal`)
    结果:[[1 3] [8 9]]
    分析:同上
    

    FindSubmatch FindStringSubmatch

    fmt.Printf("%q\n", (reg.FindSubmatch(src)))
    fmt.Printf("%q\n", (reg.FindStringSubmatch(srcStr)))
    

    FindSubmatch是Find的“Submatch”版本,这个版本返回正则表达式的子匹配项。子匹配指的是在括号内的子正则表达式,从左到右进行标号。
    子匹配0标示全部的表达式,子匹配1标示第1个括号内的子表达式,以此类推。

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:["abc-def-ghixx" "abc-def-ghi" "abc-def-" "abc-"]
    分析:“.”匹配任意字符。submatch0为 `(((abc.)def.)ghi)x*`,submatch1为`(((abc.)def.)ghi)`,submatch2为`((abc.)def.)`,submatch3为`(abc.)`,
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:["abc-def-ghi" "abc-def-ghi" "abc-def-" "abc-"]
    分析:“.”匹配任意字符。submatch0为 `(((abc.)def.)ghi)`,submatch1为`(((abc.)def.)ghi)`,submatch2为`((abc.)def.)`,submatch3为`(abc.)`,
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:["axxxbyc" "xxx" "y"]
    分析:submatch0为`a(x*)b(y|z)c`,submatch1为`(x*)`,submatch2为`(y|z)`
    
    testReg(`a*r`, `paranoabrmal`)
    结果:["ar"]
    分析:submatch0为`a*r`
    

    FindSubmatchIndex FindStringSubmatchIndex

    fmt.Printf("%d\n", (reg.FindSubmatchIndex(src)))
    fmt.Printf("%d\n", (reg.FindStringSubmatchIndex(srcStr)))
    

    FindSubmatchIndex是FindSubmatch的Index版本,返回匹配项的首尾下标

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[0 13 0 11 0 8 0 4]
    分析: `abc-def-ghixxa abc+def+ghixx`[0:13]="abc-def-ghixx"
            `abc-def-ghixxa abc+def+ghixx`[0:11]="abc-def-ghi"
            `abc-def-ghixxa abc+def+ghixx`[0:8]= "abc-def-"
            `abc-def-ghixxa abc+def+ghixx`[0:4]="abc-"
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[0 11 0 11 0 8 0 4]
    分析:同上
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:[1 8 2 5 6 7]
    分析:同上
    
    testReg(`a*r`, `paranoabrmal`)
    结果:[1 3]
    分析:同上
    

    FindAllSubmatch FindAllStringSubmatch

    fmt.Printf("%q\n", (reg.FindAllSubmatch(src, -1)))
    fmt.Printf("%q\n", (reg.FindAllStringSubmatch(srcStr, -1)))
    

    FindAllSubmatch是FindSubmatch的“All”版本,这个版本返回全部匹配项的子匹配项。
    子匹配0标示全部的表达式,子匹配1标示第1个括号内的子表达式,以此类推。

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[["abc-def-ghixx" "abc-def-ghi" "abc-def-" "abc-"] ["abc+def+ghixx" "abc+def+ghi" "abc+def+" "abc+"]]
    分析:参考FindSubmatch
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[["abc-def-ghi" "abc-def-ghi" "abc-def-" "abc-"] ["abc+def+ghi" "abc+def+ghi" "abc+def+" "abc+"]]
    分析:参考FindSubmatch
    
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:[["axxxbyc" "xxx" "y"] ["abzc" "" "z"]]
    分析:参考FindSubmatch
    
    
    testReg(`a*r`, `paranoabrmal`)
    结果:[["ar"] ["r"]]
    分析:参考FindSubmatch
    

    FindAllSubmatchIndex FindAllStringSubmatchIndex

    fmt.Printf("%d\n", (reg.FindAllSubmatchIndex(src, -1)))
    fmt.Printf("%d\n", (reg.FindAllStringSubmatchIndex(srcStr, -1)))
    

    FindAllSubmatchIndex是FindAllSubmatch的Index版本,返回匹配项的首尾下标

    testReg(`(((abc.)def.)ghi)x*`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[[0 13 0 11 0 8 0 4] [15 28 15 26 15 23 15 19]]
    分析: 参考FindSubmatchIndex
    
    testReg(`(((abc.)def.)ghi)`, `abc-def-ghixxa abc+def+ghixx`)
    结果:[[0 11 0 11 0 8 0 4] [15 26 15 26 15 23 15 19]]
    分析: 参考FindSubmatchIndex
    
    testReg(`a(x*)b(y|z)c`, `-axxxbyc- -abzc-`)
    结果:[[1 8 2 5 6 7] [11 15 12 12 13 14]]
    分析: 参考FindSubmatchIndex
    
    testReg(`a*r`, `paranoabrmal`)
    结果:[[1 3] [8 9]]
    分析: 参考FindSubmatchIndex
    

    测试代码参考了这篇文章

    相关文章

      网友评论

        本文标题:golang 正则匹配regexp接口实战学习

        本文链接:https://www.haomeiwen.com/subject/frovhxtx.html