Go语言通过regexp
标准包为正则表达式提供了官方支持
包中有三个函数判定是否匹配,匹配返回true,否则返回false,这三个函数只是输入源不同
func Match(pattern string, b []byte) (matched bool, error error) func MatchReader(pattern string, r io.RuneReader) (matched bool, error error) func MatchString(pattern string, s string) (matched bool, error error)
比如判定IP是否
func IsIP(ip string) (b bool) { if m, _ := regexp.MatchString("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", ip); !m { //点分判定IP,返回bool一般用来做判定 return false } return true }
func main() { if len(os.Args) == 1 { //判定命令行长度 fmt.Println("Usage: regexp [string]") os.Exit(1) } else if m, _ := regexp.MatchString("^[0-9]+$", os.Args[1]); m { //命令行参数格式 fmt.Println("数字") } else { fmt.Println("不是数字") } }
在其他语言中match都是拿来测试或是判定,并不能提取匹配成功的数据
在使用其他几个函数
package main import ( "fmt" "io/ioutil" "net/http" "regexp" "strings" ) //这里演示一个爬虫 func main() { resp, err := http.Get("http://www.baidu.com") //请求url if err != nil { fmt.Println("http get error.") } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) //读取网页代码,都在body标签中 if err != nil { fmt.Println("http read error") return } src := string(body) //将HTML标签全转换成小写 re, _ := regexp.Compile("\\<[\\S\\s]+?\\>") //使用函数编辑正则表达式判定表达式的合法性 src = re.ReplaceAllStringFunc(src, strings.ToLower) //replace字面意思就知道是替换函数 //去除STYLE re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>") src = re.ReplaceAllString(src, "") //去除SCRIPT re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>") src = re.ReplaceAllString(src, "") //去除所有尖括号内的HTML代码,并换成换行符 re, _ = regexp.Compile("\\<[\\S\\s]+?\\>") src = re.ReplaceAllString(src, "\n") //去除连续的换行符 re, _ = regexp.Compile("\\s{2,}") src = re.ReplaceAllString(src, "\n") fmt.Println(strings.TrimSpace(src)) }
func (re *Regexp) Find(b []byte) []byte func (re *Regexp) FindAll(b []byte, n int) [][]byte func (re *Regexp) FindAllIndex(b []byte, n int) [][]int func (re *Regexp) FindAllString(s string, n int) []string func (re *Regexp) FindAllStringIndex(s string, n int) [][]int func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int func (re *Regexp) FindIndex(b []byte) (loc []int) func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int func (re *Regexp) FindString(s string) string func (re *Regexp) FindStringIndex(s string) (loc []int) func (re *Regexp) FindStringSubmatch(s string) []string func (re *Regexp) FindStringSubmatchIndex(s string) []int func (re *Regexp) FindSubmatch(b []byte) [][]byte func (re *Regexp) FindSubmatchIndex(b []byte) []int
看下面的例子
package main import ( "fmt" "regexp" ) func main() { a := "I am learning Go language" re, _ := regexp.Compile("[a-z]{2,4}") //匹配2到4个字母 //查找符合正则的第一个 one := re.Find([]byte(a)) fmt.Println("Find:", string(one)) //查找符合正则的所有slice,n小于0表示返回全部符合的字符串,不然就是返回指定的长度 all := re.FindAll([]byte(a), -1) fmt.Println("FindAll", all) //查找符合条件的index位置,开始位置和结束位置 index := re.FindIndex([]byte(a)) fmt.Println("FindIndex", index) //查找符合条件的所有的index位置,n同上 allindex := re.FindAllIndex([]byte(a), -1) fmt.Println("FindAllIndex", allindex) re2, _ := regexp.Compile("am(.*)lang(.*)") //查找Submatch,返回数组,第一个元素是匹配的全部元素,第二个元素是第一个()里面的,第三个是第二个()里面的 //下面的输出第一个元素是"am learning Go language" //第二个元素是" learning Go ",注意包含空格的输出 //第三个元素是"uage" submatch := re2.FindSubmatch([]byte(a)) fmt.Println("FindSubmatch", submatch) for _, v := range submatch { fmt.Println(string(v)) } //定义和上面的FindIndex一样 submatchindex := re2.FindSubmatchIndex([]byte(a)) fmt.Println(submatchindex) //FindAllSubmatch,查找所有符合条件的子匹配 submatchall := re2.FindAllSubmatch([]byte(a), -1) fmt.Println(submatchall) //FindAllSubmatchIndex,查找所有字匹配的index submatchallindex := re2.FindAllSubmatchIndex([]byte(a), -1) fmt.Println(submatchallindex) }
func main() { src := []byte(` call hello alice hello bob call hello eve `) pat := regexp.MustCompile(`(?m)(call)\s+(?P<cmd>\w+)\s+(?P<arg>.+)\s*$`) res := []byte{} for _, s := range pat.FindAllSubmatchIndex(src, -1) { res = pat.Expand(res, []byte("$cmd('$arg')\n"), src, s) } fmt.Println(string(res)) }