提交 fc8c2734 编写于 作者: V vCaesar

Add 0.7.3.md syntax highlighting

上级 fee35861
......@@ -9,14 +9,17 @@ Go语言通过`regexp`标准包为正则表达式提供了官方支持,如果
## 通过正则判断是否匹配
`regexp`包中含有三个函数用来判断是否匹配,如果匹配返回true,否则返回false
```Go
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)
```
上面的三个函数实现了同一个功能,就是判断`pattern`是否和输入源匹配,匹配的话就返回true,如果解析正则出错则返回error。三个函数的输入源分别是byte slice、RuneReader和string。
如果要验证一个输入是不是IP地址,那么如何来判断呢?请看如下实现
```Go
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 {
......@@ -24,8 +27,9 @@ Go语言通过`regexp`标准包为正则表达式提供了官方支持,如果
}
return true
}
```
可以看到,`regexp`的pattern和我们平常使用的正则一模一样。再来看一个例子:当用户输入一个字符串,我们想知道是不是一次合法的输入:
```Go
func main() {
if len(os.Args) == 1 {
......@@ -37,13 +41,14 @@ Go语言通过`regexp`标准包为正则表达式提供了官方支持,如果
fmt.Println("不是数字")
}
}
```
在上面的两个小例子中,我们采用了Match(Reader|String)来判断一些字符串是否符合我们的描述需求,它们使用起来非常方便。
## 通过正则获取内容
Match模式只能用来对字符串的判断,而无法截取字符串的一部分、过滤字符串、或者提取出符合条件的一批字符串。如果想要满足这些需求,那就需要使用正则表达式的复杂模式。
我们经常需要一些爬虫程序,下面就以爬虫为例来说明如何使用正则来过滤或截取抓取到的数据:
```Go
package main
......@@ -92,18 +97,21 @@ Match模式只能用来对字符串的判断,而无法截取字符串的一部
fmt.Println(strings.TrimSpace(src))
}
```
从这个示例可以看出,使用复杂的正则首先是Compile,它会解析正则表达式是否合法,如果正确,那么就会返回一个Regexp,然后就可以利用返回的Regexp在任意的字符串上面执行需要的操作。
解析正则表达式的有如下几个方法:
```Go
func Compile(expr string) (*Regexp, error)
func CompilePOSIX(expr string) (*Regexp, error)
func MustCompile(str string) *Regexp
func MustCompilePOSIX(str string) *Regexp
```
CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法,它使用最左最长方式搜索,而Compile是采用的则只采用最左方式搜索(例如[a-z]{2,4}这样一个正则表达式,应用于"aa09aaa88aaaa"这个文本串时,CompilePOSIX返回了aaaa,而Compile的返回的是aa)。前缀有Must的函数表示,在解析正则语法的时候,如果匹配模式串不满足正确的语法则直接panic,而不加Must的则只是返回错误。
在了解了如何新建一个Regexp之后,我们再来看一下这个struct提供了哪些方法来辅助我们操作字符串,首先我们来看下面这些用来搜索的函数:
```Go
func (re *Regexp) Find(b []byte) []byte
func (re *Regexp) FindAll(b []byte, n int) [][]byte
......@@ -123,8 +131,9 @@ CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法,它使用
func (re *Regexp) FindStringSubmatchIndex(s string) []int
func (re *Regexp) FindSubmatch(b []byte) [][]byte
func (re *Regexp) FindSubmatchIndex(b []byte) []int
```
上面这18个函数我们根据输入源(byte slice、string和io.RuneReader)不同还可以继续简化成如下几个,其他的只是输入源不一样,其他功能基本是一样的:
```Go
func (re *Regexp) Find(b []byte) []byte
func (re *Regexp) FindAll(b []byte, n int) [][]byte
......@@ -134,8 +143,9 @@ CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法,它使用
func (re *Regexp) FindIndex(b []byte) (loc []int)
func (re *Regexp) FindSubmatch(b []byte) [][]byte
func (re *Regexp) FindSubmatchIndex(b []byte) []int
```
对于这些函数的使用我们来看下面这个例子
```Go
package main
......@@ -189,14 +199,16 @@ CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法,它使用
submatchallindex := re2.FindAllSubmatchIndex([]byte(a), -1)
fmt.Println(submatchallindex)
}
```
前面介绍过匹配函数,Regexp也定义了三个函数,它们和同名的外部函数功能一模一样,其实外部函数就是调用了这Regexp的三个函数来实现的:
```Go
func (re *Regexp) Match(b []byte) bool
func (re *Regexp) MatchReader(r io.RuneReader) bool
func (re *Regexp) MatchString(s string) bool
```
接下里让我们来了解替换函数是怎么操作的?
```Go
func (re *Regexp) ReplaceAll(src, repl []byte) []byte
func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
......@@ -204,15 +216,17 @@ CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法,它使用
func (re *Regexp) ReplaceAllLiteralString(src, repl string) string
func (re *Regexp) ReplaceAllString(src, repl string) string
func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string
```
这些替换函数我们在上面的抓网页的例子有详细应用示例,
接下来我们看一下Expand的解释:
```Go
func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte
func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte
```
那么这个Expand到底用来干嘛的呢?请看下面的例子:
```Go
func main() {
src := []byte(`
......@@ -227,7 +241,7 @@ CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法,它使用
}
fmt.Println(string(res))
}
```
至此我们已经全部介绍完Go语言的`regexp`包,通过对它的主要函数介绍及演示,相信大家应该能够通过Go语言的正则包进行一些基本的正则的操作了。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册