• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Go语言正则表达式的使用详解

    正则表达式是一种进行模式匹配和文本操纵的功能强大的工具。正则表达式灵活、易用,按照它的语法规则,随需构造出的匹配模式就能够从原始文本中筛选出几乎任何你想要得到的字符组合。

    准则

    使用regexp调用

    Match,MatchReader和 MatchString

    // 判断b中是够包含pattern能够组成的任意字符串
    func Match(pattern string, b []byte) (matched bool, err error)
    
    // 判断reader r中返回的字符串是否包含pattern能够组成的任意字符串
    func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)
    
    // 判断字符串s中是否包含pattern能够组成的任意字符串
    func MatchString(pattern string, s string) (matched bool, err error)
    

    Compile 和 MushCompile

    func Compile(expr string) (*Regexp, error)
    func MustCompile(str string) *Regexp

    Compile :返回 Regexp 对象,方便调用指针函数。

    MustCompile :同Compile,解析表达式失败,会panic。

    在匹配文本时,该正则表达式会尽可能早的开始匹配,并且在匹配过程中选择回溯搜索到的第一个匹配结果。这种模式被称为 leftmost-first ,另外一般情况下使用 MustCompile 即可。

    使用regexp.Regexp对象来调用

    Find 和 FindAll

    Find返回保管正则表达式re在b中的最左侧的一个匹配结果的[]byte切片。如果没有匹配到,会返回nil,最多匹配一个。

    re := regexp.MustCompile(`foo.?`)
    fmt.Printf("%q\n", re.Find([]byte(`seafood fool`)))
    re := regexp.MustCompile(`foo.?`)
    fmt.Printf("%q\n", re.FindAll([]byte(`seafood fool`), -1))

    FindAll 功能与 Find 一样,只是返回全部满足条件的数据。

    FindString 和 FindAllString

    与 Find 和 FindAll 一样,只是针对字符串string操作。

    FindIndex 和 FindAllIndex

    FindIndex , 返回 b 中满足匹配字符串部分的起始位置,同样是**“leftmost-first”**原则,loc包含起止位置。如果没有找到,直接返回 nil 。

    FindAllIndex ,功能和 FindIndex 保持一致,只是匹配多个, n 决定了匹配的位置。

    FindStringIndex 和 FindAllStringIndex

    与 FindIndex 和 FindAllIndex 使用方式类似,只是针对的是字符串string。

    FindStringSubmatch 和 FindAllStringSubmatch

    FindStringSubmatch :采用左匹配原则,最多匹配一个,如果没有的话,返回 nil 。对于返回的 []string ,分别标示匹配的字符串,子串。

    re := regexp.MustCompile(`a(x*)b(y|z)c`)
    fmt.Printf("%q\n", re.FindStringSubmatch("-axxxbyc-"))
    fmt.Printf("%q\n", re.FindStringSubmatch("-abzc-"))

    输出结果:

    ["axxxbyc" "xxx" "y"]
    ["abzc" "" "z"]

    和 FindStringSubmatch 使用类似,只是能顾选择匹配的长度, -1 表示匹配到末尾。

    re := regexp.MustCompile(`a(x*)b`)
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-", -1))
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-", -1))
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-axb-", -1))
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-ab-", -1))

    输出结果:

    [["ab" ""]]
    [["axxb" "xx"]]
    [["ab" ""] ["axb" "x"]]
    [["axxb" "xx"] ["ab" ""]]

    FindSubmatchIndex 和 FindAllSubmatchIndex

    另外, index 返回为 左闭右开 的模式,示例中的 2,2 表示空字符串的意思。 并且,不会存在重合匹配的,比如说"-axxb-ab-"去匹配 a(x*)b ,不会存在第一个 a 和最后一个 b 结合的情况,如果使用 Longest 就会匹配最长的。

    re := regexp.MustCompile(`a(x*)b`)
    // Indices:
    // 01234567 012345678
    // -ab-axb- -axxb-ab-
    fmt.Println(re.FindAllStringSubmatchIndex("-ab-", -1))
    fmt.Println(re.FindAllStringSubmatchIndex("-axxb-", -1))
    fmt.Println(re.FindAllStringSubmatchIndex("-ab-axb-", -1))
    fmt.Println(re.FindAllStringSubmatchIndex("-axxb-ab-", -1))
    fmt.Println(re.FindAllStringSubmatchIndex("-foo-", -1))
    

    输出结果:

    [[1 3 2 2]] // 2 2 表示为空
    [[1 5 2 4]]
    [[1 3 2 2] [4 7 5 6]]
    [[1 5 2 4] [6 8 7 7]]
    []


    FindStringSubmatchIndex 和 FindAllStringSubmatchIndex
    func (re *Regexp) FindStringSubmatchIndex(s string) []int
    func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int
    和 FindSubmatchIndex , FindAllSubmatchIndex 保持一致。
    
    Longest
    func (re *Regexp) Longest() 获取最长匹配的满足条件的内容。
    re := regexp.MustCompile(`a(|b)`)
    fmt.Println(re.FindString("ab"))
    re.Longest()
    fmt.Println(re.FindString("ab"))
    

    输出结果:

    a
    ab

    下面这种情况不会最长匹配。

    re := regexp.MustCompile(`a(x*)b`)
    re.Longest()
    fmt.Println(re.FindString("-axxb-ab-")) // axxb,不会存在第一个a和最后一个b组合的过程。
    

    Match,MatchString和MatchReader

    判断 b , s 和 r 返回的数据是否满足正则表达式,返回 true 或者 false 。

    NumSubexp

    返回分组的数量。

    re0 := regexp.MustCompile(`a.`)
    fmt.Printf("%d\n", re0.NumSubexp())
    
    re := regexp.MustCompile(`(.*)((a)b)(.*)a`)
    fmt.Println(re.NumSubexp())

    输出结果:

    0
    4

    ReplaceAll 和 ReplaceAllString
    func (re *Regexp) ReplaceAll(src, repl []byte) []byte
    func (re *Regexp) ReplaceAllString(src, repl string) string
    ReplaceAllString 与 ReplaceAll 使用方式相同。
    
    re := regexp.MustCompile(`a(x*)b`)
    fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("T"))) 
    fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("$1"))) // $1表示匹配的第一个子串,这是ab的中间无字符串,所以$1为空,然后使用空去替换满足正则表达式的部分。
    fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("$1W"))) // "$1W"等价与"$(1W)",值为空,将满足条件的部分完全替换为空。
    fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("${1}W"))) // ${1}匹配(x*),保留。输出-W-xxW-
    

    输出结果:

    -T-T-
    --xx-
    ---
    -W-xxW-

    s := "Hello World, 123 Go!"
    //定义一个正则表达式reg,匹配Hello或者Go
    reg := regexp.MustCompile(`(Hell|G)o`)
    
    s2 := "2019-12-01,test"
    //定义一个正则表达式reg2,匹配 YYYY-MM-DD 的日期格式
    reg2 := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
    
    //最简单的情况,用“T替换”"-ab-axxb-"中符合正则"a(x*)b"的部分
    reg3 := regexp.MustCompile("a(x*)b")
    fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) // -T-T-
    
    //${1}匹配"Hello World, 123 Go!"中符合正则`(Hell|G)`的部分并保留,去掉"Hello"与"Go"中的'o'并用"ddd"追加
    rep1 := "${1}ddd"
    fmt.Printf("%q\n", reg.ReplaceAllString(s, rep1)) // Hellddd World, 123 Gddd!
    
    //首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{4})'的'2019'保留,去掉剩余部分
    rep2 := "${1}"
    fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep2)) // 2019,test
    
    //首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'12'保留,去掉剩余部分
     rep3 := "${2}"
    fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep3)) // 12,test
    
    //首先,"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'01'保留,去掉剩余部分,并追加"13:30:12"
    rep4 := "${3}:13:30:12"
    fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep4)) // 01:13:30:12,test
    }
    
    

    ReplaceAllFunc 和 ReplaceAllStringFunc

    将匹配出来满足条件的 []byte 作为参数传入函数中。

    re := regexp.MustCompile(`[^aeiou]`)
    fmt.Println(re.ReplaceAllStringFunc("seafood fool", strings.ToUpper))

    两者使用方式类似。

    ReplaceAllLiteral 和 ReplaceAllLiteralString

    匹配字面常量,不转换。

    re := regexp.MustCompile(`a(x*)b`)
    fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "T"))
    fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "$1"))
    fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "${1}"))

    输出结果:

    -T-T-
    -$1-$1-
    -${1}-${1}-

    关于 $1 说明:

    Expand 和 ExpandString

    Expand返回新生成的将template添加到dst后面的切片。在添加时,Expand会将template中的变量替换为从src匹配的结果。match应该是被FindSubmatchIndex返回的匹配结果起止位置索引。(通常就是匹配src,除非你要将匹配得到的位置用于另一个[]byte)

    在template参数里,一个变量表示为格式如: $name 或 ${name} 的字符串,其中name是长度>0的字母、数字和下划线的序列。一个单纯的数字字符名如$1会作为捕获分组的数字索引;其他的名字对应(?P...)语法产生的命名捕获分组的名字。超出范围的数字索引、索引对应的分组未匹配到文本、正则表达式中未出现的分组名,都会被替换为空切片。

    $name格式的变量名,name会尽可能取最长序列: $1x 等价于 ${1x} 而非 ${1}x , $10 等价于 ${10} 而非 ${1}0 。因此 $name 适用在后跟空格/换行等字符的情况, ${name} 适用所有情况。

    如果要在输出中插入一个字面值 '$' ,在template里可以使用 $$ 。

    其他示例

    解析网址

    flysnowRegexp := regexp.MustCompile(`^http://www.flysnow.org/([\d]{4})/([\d]{2})/([\d]{2})/([\w-]+).html$`)
    params := flysnowRegexp.FindStringSubmatch("http://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html")
    // 返回[]string{}数据类型
    for _, param := range params {
     fmt.Println(param)
    }
    

    输出结果:

    http://www.flysnow.org/2018/01/20/golang-goquery-examples-selector.html
    2018
    01
    20
    golang-goquery-examples-selector

    总结

    到此这篇关于Go语言正则表达式的使用详解的文章就介绍到这了,更多相关Go正则表达式使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • Java使用正则表达式检索、替换String中特定字符和正则表达式的一切
    • python中使用正则表达式将所有符合条件的字段全部提取出来
    • layui 正则表达式验证使用实例详解
    • 正则表达式直接在EXCEL中使用的详细步骤
    上一篇:基于golang的简单分布式延时队列服务的实现
    下一篇:golang实现对docker容器心跳监控功能
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Go语言正则表达式的使用详解 语言,正则,表达式,的,使用,