Go多个正则表达式查找的区别

区别

Go的regexp是用正则表达式来查找、替换处理字符串的包,查找有很多方法,他们的区别如下:

函数参数类型能否全部能否子匹配返回匹配字符串或索引
Find字节数组最左边字节数组
FindAll字节数组全部字节数组
FindIndex字节数组最左边索引
FindAllIndex字节数组全部索引
FindString字符串最左边字符串
FindAllString字符串全部字符串
FindAllStringIndex字符串全部字符串
FindAllSubmatch字节数组全部字节数组
FindAllSubmatchIndex字节数组全部字节数组
FindSubmatch字节数组最左边字节数组
FindSubmatchIndex字节数组最左边字节数组
FindStringSubmatch字符串最左边字符串数组
FindStringSubmatchIndex字符串最左边字符串数组
FindAllStringSubmatch字符串全部字符串数组
FindAllStringSubmatchIndex字符串全部字符串数组

字节类型匹配模板Expand

package main_test

import (
	"fmt"
	"regexp"
	"testing"
)

func TestExpand(t *testing.T) {
	content := []byte(`
	# comment line
	option1: value1
	option2: value2

	# another comment line
	option3: value3
`)

	// 正则匹配:键值对key:value
	pattern := regexp.MustCompile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)

	// 通过命名分组类把"key: value" 转换为 "key=value"
	template := []byte("$key=$value\n")

	result := []byte{}
	for _, submatches := range pattern.FindAllSubmatchIndex(content, -1) {
		// 把匹配到的每个键值对应用到对应模板上
		result = pattern.Expand(result, template, content, submatches)
	}
	fmt.Println(string(result))
}

// option1=value1
// option2=value2
// option3=value3

这里用(?P<key>\w+)给分组命名为key,然后通过Expand将匹配到的key按照模板的样式输出给result,value同理,另外匹配必须要用FindAllSubmatchIndex的结果。

字符串类型匹配模板Expand

func TestExpandString(t *testing.T) {
	content := `
	# comment line
	option1: value1
	option2: value2

	# another comment line
	option3: value3
`

	// 解析正则
	pattern := regexp.MustCompile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)

	// 转换模板
	template := "$key=$value\n"

	result := []byte{}

	for _, submatches := range pattern.FindAllStringSubmatchIndex(content, -1) {
		// 应用
		result = pattern.ExpandString(result, template, content, submatches)
	}
	fmt.Println(string(result))
}


查找左侧第一个和所有

func TestFind(t *testing.T) {
	re := regexp.MustCompile(`foo.?`)
	fmt.Printf("%q\n", re.Find([]byte(`seafood fool`)))
}
// "food"


func TestFindAll(t *testing.T) {
	re := regexp.MustCompile(`foo.?`)
	fmt.Printf("%q\n", re.FindAll([]byte(`seafood fool`), -1))
}
// ["food" "fool"]

Find查找最左侧第一个。FindAll第二个参数是-1就是查找所有匹配,如果FindAll第二个参数是1,就跟Find一样了。
这两个方法不会返回子匹配。

字符串类型查找左侧第一个字符串

func TestFindString(t *testing.T) {
	re := regexp.MustCompile(`foo.?`)
	fmt.Printf("%q\n", re.FindString("seafood fool"))
	fmt.Printf("%q\n", re.FindString("meat"))
}

// "food"
// ""

查找索引

func TestFindAllIndex(t *testing.T) {
	content := []byte("London")
	re := regexp.MustCompile(`o.`)
	fmt.Println(re.FindAllIndex(content, 1))
	fmt.Println(re.FindAllIndex(content, -1))
}
// [[1 3]]
// [[1 3] [4 6]]

FindAllIndex会返回匹配到的分片(开始和结束索引)。

字符串类型的查找所有

func TestFindAllString(t *testing.T) {
	re := regexp.MustCompile(`a.`)
	fmt.Println(re.FindAllString("paranormal", -1))
	fmt.Println(re.FindAllString("paranormal", 2))
	fmt.Println(re.FindAllString("graal", -1))
	fmt.Println(re.FindAllString("none", -1))
}
// [ar an al]
// [ar an]
// [aa]
// []

子匹配字符串查找所有

func TestFindAllStringSubmatch(t *testing.T) {
	re := regexp.MustCompile(`a(x*)b`)
	fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-", -1))
	fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-", -1))
	fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-axb-", -1))
	fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-ab-", -1))
}

// [["ab" ""]]
// [["axxb" "xx"]]
// [["ab" ""] ["axb" "x"]]
// [["axxb" "xx"] ["ab" ""]]

子匹配字符串查找所有索引

func TestFindAllStringSubmatchIndex(t *testing.T) {
	re := regexp.MustCompile(`a(x*)b`)
	// Indices:
	//    01234567   012345678
	//    -ab-axb-   -axxb-ab-
	fmt.Println(re.FindAllStringSubmatchIndex("-ab-", -1))
	fmt.Println(re.FindAllStringSubmatchIndex("-axxb-", -1))
	fmt.Println(re.FindAllStringSubmatchIndex("-ab-axb-", -1))
	fmt.Println(re.FindAllStringSubmatchIndex("-axxb-ab-", -1))
	fmt.Println(re.FindAllStringSubmatchIndex("-foo-", -1))
}
// [[1 3 2 2]]
// [[1 5 2 4]]
// [[1 3 2 2] [4 7 5 6]]
// [[1 5 2 4] [6 8 7 7]]
// []

子匹配字节类型查找所有

func TestFindAllSubmatch(t *testing.T) {
	re := regexp.MustCompile(`foo(.?)`)
	fmt.Printf("%q\n", re.FindAllSubmatch([]byte(`seafood fool`), -1))
}

// [["food" "d"] ["fool" "l"]]

子匹配字节类型查询所有索引

func TestFindAllSubmatchIndex(t *testing.T) {
	content := []byte(`
	# comment line
	option1: value1
	option2: value2
`)
	// Regex pattern captures "key: value" pair from the content.
	pattern := regexp.MustCompile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)
	allIndexes := pattern.FindAllSubmatchIndex(content, -1)
	for _, loc := range allIndexes {
		fmt.Println(loc)
		fmt.Println("1:", string(content[loc[0]:loc[1]]))
		fmt.Println("2:", string(content[loc[2]:loc[3]]))
		fmt.Println("3:", string(content[loc[4]:loc[5]]))
	}
}

// [18 33 18 25 27 33]
// 1: option1: value1
// 2: option1
// 3: value1
// [35 50 35 42 44 50]
// 1: option2: value2
// 2: option2
// 3: value2

子匹配字节类型查询左侧第一索引

func TestFindIndex(t *testing.T) {
	content := []byte(`
	# comment line
	option1: value1
	option2: value2
`)
	// Regex pattern captures "key: value" pair from the content.
	pattern := regexp.MustCompile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)

	loc := pattern.FindIndex(content)
	fmt.Println(loc)
	fmt.Println(string(content[loc[0]:loc[1]]))
}

// [18 33]
// option1: value1

字符串子匹配最左侧

func TestFindStringSubmatch(t *testing.T) {
	re := regexp.MustCompile(`(?s)<title>(.*?)<\/title>`)
	fmt.Printf("%q\n", re.FindStringSubmatch(`<title>
	标题
	</title>`))
}

// ["<title>\n\t标题\n\t</title>" "\n\t标题\n\t"]

参考

https://github.com/google/re2/wiki/Syntax

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小龙在山东

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

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

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

打赏作者

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

抵扣说明:

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

余额充值