3.5 GO 正则表达式

Go内置了(regexp包)对正则表达式的支持,这里是一般的正则表达式常规用法的例子。

示例:

  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "regexp"
  6. )
  7. func main() {
  8. //是否匹配字符串
  9. // .匹配任意一个字符 ,*匹配零个或多个 ,优先匹配更多(贪婪)
  10. match, _ := regexp.MatchString("H(.*)d!", "Hello World!")
  11. fmt.Println(match) //true
  12. //或
  13. match, _ = regexp.Match("H(.*)d!", []byte("Hello World!"))
  14. fmt.Println(match) //true
  15. //或通过`Compile`来使用一个优化过的正则对象
  16. r, _ := regexp.Compile("H(.*)d!")
  17. fmt.Println(r.MatchString("Hello World!")) //true
  18. // 这个方法返回匹配的子串
  19. fmt.Println(r.FindString("Hello World! world")) //Hello World!
  20. //同上
  21. fmt.Println(string(r.Find([]byte("Hello World!")))) //Hello World!
  22. // 这个方法查找第一次匹配的索引
  23. // 的起始索引和结束索引,而不是匹配的字符串
  24. fmt.Println(r.FindStringIndex("Hello World! world")) //[0 12]
  25. // 这个方法返回全局匹配的字符串和局部匹配的字符,匹配最大的子字符串一次。
  26. // 它和r.FindAllStringSubmatch("Hello World! world",1) 等价。 比如
  27. // 这里会返回匹配`H(.*)d!`的字符串
  28. // 和匹配`(.*)`的字符串
  29. fmt.Println(r.FindStringSubmatch("Hello World! world")) //[Hello World! ello Worl]
  30. // 和上面的方法一样,不同的是返回全局匹配和局部匹配的
  31. // 起始索引和结束索引
  32. fmt.Println(r.FindStringSubmatchIndex("Hello World! world")) //[0 12 1 10]
  33. // 这个方法返回所有正则匹配的字符,不仅仅是第一个
  34. fmt.Println(r.FindAllString("Hello World! Held! world", -1)) //[Hello World! Held!]
  35. // 这个方法返回所有全局匹配和局部匹配的字符串起始索引,只匹配最大的串
  36. // 和结束索引
  37. fmt.Println(r.FindAllStringSubmatchIndex("Hello World! world", -1)) //[[0 12 1 10]]
  38. fmt.Println(r.FindAllStringSubmatchIndex("Hello World! Held! world", -1)) //[[0 18 1 16]]
  39. // 为这个方法提供一个正整数参数来限制匹配数量
  40. res, _ := regexp.Compile("H([a-z]+)d!")
  41. fmt.Println(res.FindAllString("Hello World! Held! Hellowrld! world", 2)) //[Held! Hellowrld!]
  42. fmt.Println(r.FindAllString("Hello World! Held! world", 2)) //[Hello World! Held!]
  43. //注意上面两个不同,第二参数是一最大子串为单位计算。
  44. // regexp包也可以用来将字符串的一部分替换为其他的值
  45. fmt.Println(r.ReplaceAllString("Hello World! Held! world", "html")) //html world
  46. // `Func`变量可以让你将所有匹配的字符串都经过该函数处理
  47. // 转变为所需要的值
  48. in := []byte("Hello World! Held! world")
  49. out := r.ReplaceAllFunc(in, bytes.ToUpper)
  50. fmt.Println(string(out))
  51. // 在 b 中查找 reg 中编译好的正则表达式,并返回第一个匹配的位置
  52. // {起始位置, 结束位置}
  53. b := bytes.NewReader([]byte("Hello World!"))
  54. reg := regexp.MustCompile(`\w+`)
  55. fmt.Println(reg.FindReaderIndex(b)) //[0 5]
  56. // 在 字符串 中查找 r 中编译好的正则表达式,并返回所有匹配的位置
  57. // {{起始位置, 结束位置}, {起始位置, 结束位置}, ...}
  58. // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
  59. fmt.Println(r.FindAllIndex([]byte("Hello World!"), -1)) //[[0 12]]
  60. //同上
  61. fmt.Println(r.FindAllStringIndex("Hello World!", -1)) //[[0 12]]
  62. // 在 s 中查找 re 中编译好的正则表达式,并返回所有匹配的内容
  63. // 同时返回子表达式匹配的内容
  64. // {
  65. // {完整匹配项, 子匹配项, 子匹配项, ...},
  66. // {完整匹配项, 子匹配项, 子匹配项, ...},
  67. // ...
  68. // }
  69. // 只查找前 n 个匹配项,如果 n < 0,则查找所有匹配项
  70. reg = regexp.MustCompile(`(\w)(\w)+`) //[[Hello H o] [World W d]]
  71. fmt.Println(reg.FindAllStringSubmatch("Hello World!", -1)) //[[Hello H o] [World W d]]
  72. // 将 template 的内容经过处理后,追加到 dst 的尾部。
  73. // template 中要有 $1、$2、${name1}、${name2} 这样的“分组引用符”
  74. // match 是由 FindSubmatchIndex 方法返回的结果,里面存放了各个分组的位置信息
  75. // 如果 template 中有“分组引用符”,则以 match 为标准,
  76. // 在 src 中取出相应的子串,替换掉 template 中的 $1、$2 等引用符号。
  77. reg = regexp.MustCompile(`(\w+),(\w+)`)
  78. src := []byte("Golang,World!") // 源文本
  79. dst := []byte("Say: ") // 目标文本
  80. template := []byte("Hello $1, Hello $2") // 模板
  81. m := reg.FindSubmatchIndex(src) // 解析源文本
  82. // 填写模板,并将模板追加到目标文本中
  83. fmt.Printf("%q", reg.Expand(dst, template, src, m))
  84. // "Say: Hello Golang, Hello World"
  85. // LiteralPrefix 返回所有匹配项都共同拥有的前缀(去除可变元素)
  86. // prefix:共同拥有的前缀
  87. // complete:如果 prefix 就是正则表达式本身,则返回 true,否则返回 false
  88. reg = regexp.MustCompile(`Hello[\w\s]+`)
  89. fmt.Println(reg.LiteralPrefix())
  90. // Hello false
  91. reg = regexp.MustCompile(`Hello`)
  92. fmt.Println(reg.LiteralPrefix())
  93. // Hello true
  94. text := `Hello World! hello world`
  95. // 正则标记“非贪婪模式”(?U)
  96. reg = regexp.MustCompile(`(?U)H[\w\s]+o`)
  97. fmt.Printf("%q\n", reg.FindString(text)) // Hello
  98. // 切换到“贪婪模式”
  99. reg.Longest()
  100. fmt.Printf("%q\n", reg.FindString(text)) // Hello Wo
  101. // 统计正则表达式中的分组个数(不包括“非捕获的分组”)
  102. fmt.Println(r.NumSubexp()) //1
  103. //返回 r 中的“正则表达式”字符串
  104. fmt.Printf("%s\n", r.String())
  105. // 在 字符串 中搜索匹配项,并以匹配项为分割符,将 字符串 分割成多个子串
  106. // 最多分割出 n 个子串,第 n 个子串不再进行分割
  107. // 如果 n < 0,则分割所有子串
  108. // 返回分割后的子串列表
  109. fmt.Printf("%q\n", r.Split("Hello World! Helld! hello", -1)) //["" " hello"]
  110. // 在 字符串 中搜索匹配项,并替换为 repl 指定的内容
  111. // 如果 rep 中有“分组引用符”($1、$name),则将“分组引用符”当普通字符处理
  112. // 全部替换,并返回替换后的结果
  113. s := "Hello World, hello!"
  114. reg = regexp.MustCompile(`(Hell|h)o`)
  115. rep := "${1}"
  116. fmt.Printf("%q\n", reg.ReplaceAllLiteralString(s, rep)) //"${1} World, hello!"
  117. // 在 字符串 中搜索匹配项,然后将匹配的内容经过 repl 处理后,替换 字符串 中的匹配项
  118. // 如果 repb 的返回值中有“分组引用符”($1、$name),则将“分组引用符”当普通字符处理
  119. // 全部替换,并返回替换后的结果
  120. ss := []byte("Hello World!")
  121. reg = regexp.MustCompile("(H)ello")
  122. repb := []byte("$0$1")
  123. fmt.Printf("%s\n", reg.ReplaceAll(ss, repb))
  124. // HelloH World!
  125. fmt.Printf("%s\n", reg.ReplaceAllFunc(ss,
  126. func(b []byte) []byte {
  127. rst := []byte{}
  128. rst = append(rst, b...)
  129. rst = append(rst, "$1"...)
  130. return rst
  131. }))
  132. // Hello$1 World!
  133. }

小结:

1、

  1. r, _ := regexp.Compile("H(.*)d!")

可用一下代替

  1. r := regexp.MustCompile("H(.*)d!")

两者区别 MustCompile 少一个返回值err

看源码

  1. // Compile parses a regular expression and returns, if successful,
  2. // a Regexp object that can be used to match against text.
  3. //...
  4. // For POSIX leftmost-longest matching, see CompilePOSIX.
  5. func Compile(expr string) (*Regexp, error) {
  6. return compile(expr, syntax.Perl, false)
  7. }
  8. // MustCompile is like Compile but panics if the expression cannot be parsed.
  9. // It simplifies safe initialization of global variables holding compiled regular
  10. // expressions.
  11. func MustCompile(str string) *Regexp {
  12. regexp, err := Compile(str)
  13. if err != nil {
  14. panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
  15. }
  16. return regexp
  17. }

2、regexp的处理byte的方法都有个string方法对应,两者功能一样。

例如:

  1. regexp.Match()
  2. regexp.MatchString()

links