Go常用正则函数整理

前言

在Go语言中,标准库regexp提供了丰富的API来处理正则表达式,支持编译、匹配、查找、替换等操作。以下是一个Go标准库正则函数的常用大全教程及部分使用示例。
在这里插入图片描述

Go标准库常用正则函数

  1. Compile:编译正则表达式,返回一个可用于匹配、查找、替换等操作的*Regexp对象。
  2. MustCompile:功能与Compile相同,但在正则表达式无法编译时会引发panic。
  3. Match:检查字节切片中是否存在匹配正则表达式的子序列。
  4. MatchString:检查字符串中是否存在匹配正则表达式的子串。
  5. Find:在字节切片中查找正则表达式的第一个匹配项,并返回匹配项的位置和子匹配项。
  6. FindString:在字符串中查找正则表达式的第一个匹配项,并返回该匹配项。
  7. FindAll:在字节切片中查找正则表达式的所有匹配项,并返回它们的位置和子匹配项。
  8. FindAllString:在字符串中查找正则表达式的所有匹配项,并返回它们的切片。
  9. ReplaceAll:在字节切片中查找正则表达式的所有匹配项,并将它们替换为指定的替换字符串,返回新的字节切片。
  10. ReplaceAllString:在字符串中查找正则表达式的所有匹配项,并将它们替换为指定的替换字符串,返回新的字符串。
  11. ReplaceAllLiteralString:与ReplaceAllString类似,但不考虑替换字符串中的任何正则表达式元字符。
  12. Expand:根据正则表达式匹配的结果和模板字符串来构造一个新的字符串。
  13. QuoteMeta:将字符串中的特殊正则表达式元字符转义,以便它们可以被视为普通字符。

使用示例

示例1:编译并匹配字符串
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re, err := regexp.Compile(`\d+`)
    if err != nil {
        panic(err)
    }
    fmt.Println(re.MatchString("Hello 123, this is a test.")) // 输出: true
}
示例2:查找并替换字符串中的数字
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\d+`)
    result := re.ReplaceAllString("Price: 100 USD, Discount: 20%", "XXX")
    fmt.Println(result) // 输出: Price: XXX USD, Discount: XXX%
}
示例3:提取子匹配项
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(\w+)-(\d+)`)
    str := "user-1234"
    matches := re.FindStringSubmatch(str)
    if len(matches) > 0 {
        fmt.Println("Full match:", matches[0])    // Full match: user-1234
        fmt.Println("User:", matches[1])          // User: user
        fmt.Println("ID:", matches[2])            // ID: 1234
    }
}
示例4:逐行匹配
package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(?m)^go.*$`)
    str := "go is fun\nhello\ngo again"
    matches := re.FindAllString(str, -1)
    fmt.Println(matches) // 输出: [go is fun go again]
}

示例5:使用FindAllString提取所有匹配项

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\b\w+\b`) // 匹配单词边界之间的单词字符序列
    str := "Hello, world! This is a test."
    matches := re.FindAllString(str, -1) // -1 表示查找所有匹配项
    fmt.Println(matches) // 输出: [Hello world This is a test]
}

示例6:使用Expand根据模板替换

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(\w+), (\w+)!`)
    src := "Alice, Bob! Hello, World!"
    result := re.ExpandString(nil, "Hi $2, $1!", re.FindStringSubmatch(src))
    fmt.Println(result) // 输出: Hi Bob, Alice!
}

示例7:使用Split按正则表达式分割字符串

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\s+`) // 匹配一个或多个空白字符
    str := "Hello    world!    This   is   a   test."
    parts := re.Split(str, -1) // -1 表示分割所有匹配项
    fmt.Println(parts) // 输出: [Hello world! This is a test.]
}

示例8:使用FindStringIndex获取匹配项的位置

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\d+`) // 匹配一个或多个数字
    str := "There are 123 apples and 456 oranges."
    loc := re.FindStringIndex(str)
    if loc != nil {
        fmt.Printf("Found at: %d to %d\n", loc[0], loc[1])
        fmt.Printf("Matched text: %s\n", str[loc[0]:loc[1]])
    }
    // 输出:
    // Found at: 7 to 10
    // Matched text: 123
}

示例9:使用FindAllStringIndex获取所有匹配项的位置

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`\b\w+\b`) // 匹配单词
    str := "Hello, world! This is a test."
    indices := re.FindAllStringIndex(str, -1)
    for _, loc := range indices {
        fmt.Printf("Found at: %d to %d\n", loc[0], loc[1])
    }
    // 输出所有单词的位置
}

示例10:使用CompilePOSIX编译POSIX风格的正则表达式

虽然CompilePOSIX在现代Go程序中使用较少,因为它限制了正则表达式的功能,但以下是一个示例:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re, err := regexp.CompilePOSIX(`^[a-zA-Z0-9]+$`)
    if err != nil {
        panic(err)
    }
    matched := re.MatchString("username123")
    fmt.Println(matched) // 输出: true
}

请注意,CompilePOSIX使用的是POSIX BRE(基本正则表达式)语法,与Go标准库中的Compile(使用Perl兼容的正则表达式语法)不同。
当然可以,以下是更多关于Go标准库regexp包的使用示例,涵盖了更广泛的功能和场景:

示例11:忽略大小写匹配

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(?i)hello`) // 使用(?i)标志来忽略大小写
    str := "Hello, world! hello again."
    matched := re.MatchString(str)
    fmt.Println(matched) // 输出: true
}

注意:虽然Go的regexp包本身没有直接的忽略大小写编译选项(如Python的re.IGNORECASE),但你可以通过在正则表达式内部使用(?i)标志(如果正则表达式引擎支持的话,但请注意Go的标准库并不直接支持(?i),这里只是为了说明概念。在Go中,你应该使用regexp.Compile时传入的regexp.IgnoreCase选项)。然而,Go的标准做法是在编译正则表达式时传递regexp.IgnoreCase选项:

re := regexp.MustCompile(`hello`, regexp.IgnoreCase)

示例12:使用NamedCaptureGroups捕获命名组

Go标准库的regexp包不直接支持命名捕获组(如Python的(?P<name>pattern)),但你可以通过索引来访问捕获组。不过,你可以通过命名你的正则表达式组来在代码中实现类似的功能,尽管这不是由正则表达式引擎直接支持的。

示例13:匹配电子邮件地址

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$`)
    emails := []string{
        "example@example.com",
        "invalid-email",
        "another.valid.email@domain.co.uk",
    }
    for _, email := range emails {
        if re.MatchString(email) {
            fmt.Println(email, "is a valid email")
        } else {
            fmt.Println(email, "is not a valid email")
        }
    }
}

示例14:替换字符串中的URL

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`https?://[\w./?=%&\-]+`)
    str := "Visit https://example.com or http://another.example.org for more info."
    result := re.ReplaceAllString(str, "[URL]")
    fmt.Println(result) // 输出: Visit [URL] or [URL] for more info.
}

示例15:使用SubexpNames(虽然Go标准库不直接支持)

由于Go标准库的regexp包不支持命名捕获组,因此没有SubexpNames方法。但是,你可以通过手动维护一个与你的正则表达式中捕获组相对应的名称映射来实现类似的功能。

示例16:使用ReplaceFunc进行更复杂的替换

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    re := regexp.MustCompile(`\b\w+\b`)
    str := "Hello, world! This is a test."
    result := re.ReplaceAllStringFunc(str, func(match string) string {
        return strings.ToUpper(match)
    })
    fmt.Println(result) // 输出: HELLO, WORLD! THIS IS A TEST.
}

这个示例展示了如何使用ReplaceAllStringFunc方法来对每个匹配项执行一个自定义的替换函数,这里是将所有单词转换为大写。

总结

这些示例应该能够为你提供关于如何在Go中使用regexp包的更多想法和技巧。记得在实际应用中根据你的具体需求选择合适的函数和方法。在实际开发中,你可以根据具体需求选择合适的函数和方法。请注意,这里只提供了部分常用函数和示例。在实际应用中,regexp包的功能远不止于此,您还可以根据需要使用SplitFindIndexFindStringIndex等其他函数。此外,正则表达式的性能也是一个需要注意的问题。在设计正则表达式时,应尽量避免复杂的嵌套和回溯,以提高匹配效率。同时,对于需要频繁使用的正则表达式,建议使用CompileMustCompile进行预编译,以提高执行效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bobo-rs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值