查找值

是否匹配

  • MatchString(pattern string, s string) (matched bool, err error)
  • 除了MatchString外,对于其他的正则匹配,需要使用Compile函数来使用一个优化过的正则对象
1
2
3
4
5
6
7
MatchString(s string)
Match(b []byte)
go里面函数名不带String的输入都是[]byte

sentence = "3214521421"
match, err := regexp.MatchString("[0-9]", sentence)
这里返回的match是bool

查找具体值

  • FindString(s string) string 找第一个匹配字符
  • FindAllString(s string, n int) []string n可控制返回匹配数,若为负数返回全部匹配字符
1
2
3
4
5
6
7
8
9
10
11
tempReg := "[0-9]"
tempRegCom, err := regexp.Compile(tempReg)
if err == nil{
result1 := tempRegCom.FindString("2134214214gfdsgf")
fmt.Println("result1",result1)
result2 := tempRegCom.FindAllString("2134214214",-10)
fmt.Println("result2",result2)
}

result1 2
result2 [2 1 3 4 2 1 4 2 1 4]

Compile函数:

*Compile(expr string) (Regexp, error)

*MustCompile(str string) Regexp

1
2
3
4
5
tempReg := "[0-9]"
tempRegMustCom := regexp.MustCompile(tempReg)
tempRegCom, err := regexp.Compile(tempReg)
注意:使用MustCompile时若正则出错会导致panic
当使用正则表达式来创建常量的时候,你可以使用`MustCompile`

查找索引

  • FindStringIndex(s string) (loc []int)

  • FindAllStringIndex(s string, n int) [][]int

1
2
3
4
5
6
7
8
9
10
11
tempReg := "[0-9]"
tempRegCom, err := regexp.Compile(tempReg)
if err == nil{
result1 := tempRegCom.FindStringIndex("2134214214gfdsgf")
fmt.Println("result1",result1)
result2 := tempRegCom.FindAllStringIndex("2134214214",-10)
fmt.Println("result2",result2)
}

result1 [0 1]
result2 [[0 1] [1 2] [2 3] [3 4] [4 5] [5 6] [6 7] [7 8] [8 9] [9 10]]

查找替换

  • ReplaceAllString(src, repl string) string
  • ReplaceAllStringFunc(src string, repl func(string) string) string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tempReg := "[0-9]"
tempRegCom, err := regexp.Compile(tempReg)
if err == nil{
result1 := tempRegCom.ReplaceAllString("2134214214gfdsgf"," ")
fmt.Println("result1",result1)
}

result1 gfdsgf
------------------------------------------------------
str := "[a-z]"
r := regexp.MustCompile(str)
in := "fdsagsa"
out := r.ReplaceAllStringFunc(in, strings.ToUpper)
fmt.Println(string(out))

FDSAGSA

子匹配

  • FindAllStringSubmatch(s string, n int) [][]string

  • FindAllStringSubmatchIndex(s string, n int) [][]int

1
2
3
4
5
6
7
8
9
tempReg := "[\w-]+@([\w]+(?:\.[\w]+)+)"
tempRegCom, err := regexp.Compile(tempReg)
if err == nil{
matched := tempRegCom.FindAllStringSubmatch("abc@gmail.com",-1)
for _, match := range matched {
fmt.Printf("email is: %s, domain is: %s\n", match[0], match[1])
}
}
email is: abc@gmail.com, domain is: gmail.com

命名分组

命名分组就是给具有默认分组编号的组另外再给一个别名。命名分组的语法格式如下:

1
(?P<name>正则表达式)#name是一个合法的标识符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
str := `Alice 20 alice@gmail.com`
re := regexp.MustCompile(`(?P<name>[a-zA-Z]+)\s+(?P<age>\d+)\s+(?P<email>\w+@\w+(?:\.\w+)+)`)
match := re.FindStringSubmatch(str)
groupNames := re.SubexpNames()
fmt.Printf("%v, %v, %d, %d\n", match, groupNames, len(match), len(groupNames))
result := make(map[string]string)

for i, name := range groupNames {
if i != 0 && name != "" { // 第一个分组为空(也就是整个匹配)
result[name] = match[i]
}
}
fmt.Println(result)

[Alice 20 alice@gmail.com Alice 20 alice@gmail.com], [ name age email], 4, 4
map[name:Alice age:20 email:alice@gmail.com]

其他

MatchString与编译后的matchString的时间消耗对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
t1 := time.Now()
tempReg := "[0-9]"
tempRegCom := regexp.MustCompile(tempReg)
for i:=1; i<100000;i++ {
tempRegCom.MatchString("472834213421421")
}
fmt.Println(time.Since(t1))
t2 := time.Now()
for i:=1; i<100000; i++{
regexp.MatchString("[0-9]","472834213421421")
}
fmt.Println(time.Since(t2))

## 32.241759ms
## 2.228327551s

func QuoteMeta(s string) string 将字符串 s 中的“特殊字符”转换为其“转义格式”
特殊字符有:.+*?()|[]{}^$

1
2
3
4
func main() {
fmt.Println(regexp.QuoteMeta("(?P:Hello) [a-z]"))
// \(\?P:Hello\) \[a-z\]
}

几个正则场景

  1. 可以匹配:(你吃饭了吗)
    不能匹配:( 你没有吃饭吗)
1
2
3
4
5
result1,_ := regexp.MatchString("你[^没有]*?吃饭了","你吃饭了吗")
result2,_ := regexp.MatchString("你[^没有]*?吃饭了","你没有吃饭吗")
fmt.Println(result1, result2)

true false
  1. 查找星期几
1
WeekDayRegExp = "(星期|周|礼拜)([一二三四五六1-6]|日|天)"
1
2
3
4
5
6
7
8
9
10
11
## 加入上下个星期几
DayNoRegExp := "(下{0,2}个?)?" + "(上{0,2}个?)?" + WeekDayRegExp

sentence := "下个星期一下周一下下个礼拜一上礼拜一星期一上周一上上个周一"

WeekDayRegExp := "(周|星期|礼拜)([一二三四五六1-6]|日|天)"
DayNoRegExp := "(下{0,2}个?)?" + "(上{0,2}个?)?" + WeekDayRegExp
tmp, _ := regexp.Compile(DayNoRegExp)
fmt.Println(tmp.FindAllString(sentence,-1))

[下个星期一 下周一 下下个礼拜一 上礼拜一 星期一 上周一 上上个周一]
  1. 查找手机号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
11位数字
13 + 9位任意数字
15[012356789] + 8位任意数字
18[0256789]+8位任意数字
170[059]+7位任意数字

\b(13\d{9}|15[0-35-9]\d{8}|18[025-9]\d{8}|170[059]\d{7})\b

\b是为了防止类似153122108880123456也匹配成功
\b 的描述:匹配一个零宽单词边界
\B 的描述:匹配一个零宽非单词边界

CellSentence1 := "我的电话是:153122108880123456"
CellSentence2 := "我的电话是:15312210888"
CellReg := "\\b(13\\d{9}|15[0-35-9]\\d{8}|18[025-9]\\d{8}|170[059]\\d{7})\\b"
CellRegR := regexp.MustCompile(CellReg)
fmt.Println(CellRegR.FindAllString(CellSentence1,-1))
fmt.Println(CellRegR.FindAllString(CellSentence2,-1))

[]
[15312210888]