2.17 Go之正则表达式:regexp包

2.17 Go之正则表达式:regexp包

正则表达式的作用

根据需求构造出想要得到的字符组合

正则表达式的语法规则

组成:

由普通字符(例如字符az)以及特殊字符(称为"元字符")构成的文字序列,可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

字符

语法说明表达式示例匹配结果
一般字符 匹配自身 abc abc
. 匹配任意除换行符"\n"外的字符, 在 DOTALL 模式中也能匹配换行符 a.c abc
\ 转义字符,使后一个字符改变原来的意思; 如果字符串中有字符 * 需要匹配,可以使用 * 或者字符集[*]。 a.c a\c a.c a\c
[...] 字符集(字符类),对应的位置可以是字符集中任意字符。 字符集中的字符可以逐个列出,也可以给出范围,如 [abc] 或 [a-c], 第一个字符如果是 ^ 则表示取反,如 abc 表示除了abc之外的其他字符。 a[bcd]e abe 或 ace 或 ade
\d 数字:[0-9] a\dc a1c
\D 非数字:[ ^\d ] a\Dc abc
\s 空白字符:[<空格>\t\r\n\f\v] a\sc a c
\S 非空白字符:[ ^\s ] a\Sc abc
\w 单词字符:[A-Za-z0-9] a\wc abc
\W 非单词字符:[ ^\w ] a\Wc a c

数量词(用在字符或(...)之后)

语法说明表达式示例匹配结果
* 匹配前一个字符 0 或无限次 abc* ab 或 abccc
+ 匹配前一个字符 1 次或无限次 abc+ abc 或 abccc
? 匹配前一个字符 0 次或 1 次 abc? ab 或 abc
{m} 匹配前一个字符 m 次 ab{2}c abbc
{m,n} 匹配前一个字符 m 至 n 次,m 和 n 可以省略,若省略 m,则匹配 0 至 n 次; 若省略 n,则匹配 m 至无限次 ab{1,2}c abc 或 abbc

边界匹配

语法说明表达式示例匹配结果
^ 匹配字符串开头,在多行模式中匹配每一行的开头 ^abc abc
$ 匹配字符串末尾,在多行模式中匹配每一行的末尾 abc$ abc
\A 仅匹配字符串开头 \Aabc abc
\Z 仅匹配字符串末尾 abc\Z abc
\b 匹配 \w 和 \W 之间 a\b!bc a!bc
\B [^\b] a\Bbc abc

逻辑、分组

语法说明表达式示例匹配结果
| | 代表左右表达式任意匹配一个,优先匹配左边的表达式 abc|def abc 或 def
(...) 括起来的表达式将作为分组,分组将作为一个整体,可以后接数量词 (abc){2} abcabc
(?P<name>...) 分组,功能与 (...) 相同,但会指定一个额外的别名 (?P<id>abc){2} abcabc
<number> 引用编号为 <number> 的分组匹配到的字符串 (\d)abc\1 1abe1 或 5abc5
(?P=name) 引用别名为 <name> 的分组匹配到的字符串 (?P<id>\d)abc(?P=id) 1abe1 或 5abc5

特殊构造(不作为分组)

语法说明表达式示例匹配结果
(?:...) (…) 的不分组版本,用于使用 "|" 或后接数量词 (?:abc){2} abcabc
(?iLmsux) iLmsux 中的每个字符代表一种匹配模式,只能用在正则表达式的开头,可选多个 (?i)abc AbC
(?#...) # 后的内容将作为注释被忽略。 abc(?#comment)123 abc123
(?=...) 之后的字符串内容需要匹配表达式才能成功匹配 a(?=\d) 后面是数字的 a
(?!...) 之后的字符串内容需要不匹配表达式才能成功匹配 a(?!\d) 后面不是数字的 a
(?<=...) 之前的字符串内容需要匹配表达式才能成功匹配 (?<=\d)a 前面是数字的a
(?<!...) 之前的字符串内容需要不匹配表达式才能成功匹配 (?<!\d)a 前面不是数字的a

Regexp包的使用

匹配指定类型的字符串:--->应用了字符匹配的.

package main

import (
   "fmt"
   "regexp"
)

/*
使用regexp包下的函数进行指定类型字符串的匹配
*/
func main() {
   buf := "abc azc a7c aac 888 a9c tac"

   /* 解析正则表达式,如果成功,返回解析器 */
   regeNo1 := regexp.MustCompile(`a.c`)
   // 为空,返回异常
   if regeNo1 == nil {
       fmt.Println("regexp error")
       return
  }

   // 根据正则规则提取关键信息
   result1 := regeNo1.FindAllStringSubmatch(buf, -1)
   fmt.Println("结果为:",  result1)
}

匹配 a 和 c 中间包含一个数字的字符串:--->使用字符集匹配

package main

import (
   "fmt"
   "regexp"
)

/*
使用regexp包下的函数进行指定类型字符串的匹配
*/
func main() {
   buf := "abc azc a7c aac 888 a9c tac"

   /* 解析正则表达式,如果成功,返回解析器 */
   regeNo1 := regexp.MustCompile(`a[0-9]c`)
   // 为空,返回异常
   if regeNo1 == nil {
       fmt.Println("regexp error")
       return
  }

   // 根据正则规则提取关键信息
   result1 := regeNo1.FindAllStringSubmatch(buf, -1)
   fmt.Println("结果为:",  result1)
}

使用\d来匹配ac中间包含一个数字的字符串:

package main

import (
   "fmt"
   "regexp"
)

/*
使用regexp包下的函数进行指定类型字符串的匹配
*/
func main() {
   buf := "abc azc a7c aac 888 a9c tac"

   /* 解析正则表达式,如果成功,返回解析器 */
   regeNo1 := regexp.MustCompile(`a\dc`)
   // 为空,返回异常
   if regeNo1 == nil {
       fmt.Println("regexp error")
       return
  }

   // 根据正则规则提取关键信息
   result1 := regeNo1.FindAllStringSubmatch(buf, -1)
   fmt.Println("结果为:",  result1)
}

匹配div标签中的内容:

package main

import (
   "fmt"
   "regexp"
)

/*
匹配<div>标签中的内容
*/
func main() {
   // 声明html变量
   buf := `
   <!DOCTYPE html>
<html lang="zh-CN">
<head>
   <meta charset="UTF-8">
   <title>Lucifer's Home</title>
</head>
<body>
   <div>WelCome!</div>
   <div>This is My Home:
       房间A
       房间B
       房间C
   </div>
   <div>洗手间</div>
   <div>卫生间</div>
</body>
</html>
`
   // 使用解析正则表达式--->匹配div当中的内容
   reg := regexp.MustCompile(`<div>(?s:(.*?))</div>`)
   if reg == nil {
       fmt.Println("内容错误!")
       return
  }

   // 提取关键信息
   result := reg.FindAllStringSubmatch(buf, -1)

   // 过滤掉<>和</>
   for _, text := range result {
       fmt.Println("text[1] = ", text[1])
  }
}

通过Compile方法返回一个Regexp对象,实现匹配,查找,替换相关的功能:

package main

import (
   "fmt"
   "regexp"
   "strconv"
)

/*
获取regexp对象,实现匹配、查找、替换等功能
*/
func main() {
   // 提供目标串
   searchIn := "John: 2578.34 William: 4567.23 Steve: 5632.18"
   // 使用正则表达式匹配数字
   pat := "[0-9]+.[0-9]+"

   // 提供函数去匹配字符
   f := func(s string) string {
       // 使用strconv包下提供的函数进行字符匹配
       v, _ := strconv.ParseFloat(s, 32)
       // 返回取出的值
       result := strconv.FormatFloat(v * 2, 'f', 2, 32)
       return result
  }

   // 使用math包下的函数匹配提供的目标串
   if ok, _ := regexp.Match(pat, []byte(searchIn)); ok {
       fmt.Println("找到结果!")
  }

   // 获取compile对象
   re, _ := regexp.Compile(pat)

   // 将匹配部分替换为"**.*"
   str := re.ReplaceAllString(searchIn, "**.*")
   fmt.Println(str)

   // 参数为函数时替换为函数处理的结果
   res := re.ReplaceAllStringFunc(searchIn, f)
   fmt.Println(res)
}

Compile方法可以解析并返回一个正则表达式,如果成功返回,则说明该正则表达式正确可用于匹配文本

posted @   俊king  阅读(446)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示