2.17 Go之正则表达式:regexp包
正则表达式的作用
根据需求构造出想要得到的字符组合
正则表达式的语法规则
组成:
由普通字符(例如字符a到z)以及特殊字符(称为"元字符")构成的文字序列,可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
字符
| 语法 | 说明 | 表达式示例 | 匹配结果 | 
|---|---|---|---|
| 一般字符 | 匹配自身 | 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来匹配a和c中间包含一个数字的字符串:
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)
}
    It's a lonely road!!!
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号