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

总览

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

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

测试代码参考了这篇文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,152评论 0 4
  • re模块手册 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以...
    喜欢吃栗子阅读 3,907评论 0 13
  • 冲突浓度厌恶感逐渐消逝 看了眼日期最后一次沟通是一周前 感觉已经过了大半个月 感觉这一周里自己经历了好多事 内蒙都...
    李瑞秋阅读 276评论 2 1
  • 青春不老.我们不散. 那谁...你好! 很高兴第二次认识你! 你给我上了一堂很宝贵的课....
    淼儿22阅读 409评论 0 0