一些小修改

This commit is contained in:
astaxie
2012-10-07 17:21:55 +08:00
parent abd35ffce8
commit 2a0d5d7969
2 changed files with 356 additions and 351 deletions

25
7.3.md
View File

@@ -1,11 +1,11 @@
#7.3 正则处理
正则表达式是进行模式匹配和文本操纵的一种复杂而强大的工具。虽然正则表达式没有纯粹的文本匹配速度那么快,但应用起来相当的灵活。正则表达式通过简单的语法(一些简单的符号)构造模式能够匹配几乎任何可以想得到的字符组合。如果你在Web开发中需要从一些文本数据源中获取数据那么正则表达式就能够帮你从这些数据源提取出有意义的信息。
正则表达式是一种进行模式匹配和文本操纵的复杂而强大的工具。虽然正则表达式纯粹的文本匹配效率低,但是它却更灵活。按照它的语法规则,随需构造出的匹配模式能够从原始文本中筛选出几乎任何想你要得到的字符组合。如果你在Web开发中需要从一些文本数据源中获取数据,那么你只需要按照它的语法规则,随需构造出正确的模式字符串就能够从原数据源提取出有意义的文本信息。
Go语言标准包里面已经包含有`regexp`,实现了正则表达式的搜索匹配接受和python、perl或者其他语言一样的正则表达式语法更准确的说它实现了RE2标准除了`\C`详细的语法描述参考http://code.google.com/p/re2/wiki/Syntax 如果你在其他语言里面使用过正则Go实现的正则语法基本都一致那么只需要了解一下`regexp`包里面的一些函数参数就可以了
Go语言通过`regexp`标准包为正则表达式提供了官方支持如果你已经使用过其他编程语言提供的正则相关功能那么你应该对Go语言版本的不会太陌生但是它们之间也有一些小的差异因为Go实现的是RE2标准除了\C详细的语法描述参考http://code.google.com/p/re2/wiki/Syntax。
其实字符串处理我们可以使用`strings`包来进行搜索(Contains、Index)、替换(Replace)和解析(Split、Join)等操作,但是这些都是简单的字符串操作,他们的搜索都是大小写敏感,而且固定的字符串,如果我们需要匹配可变的那种就没办法实现了,当然如果`strings`包能解决你的问题,那么就尽量使用它来解决。因为他们足够简单、而且性能和可读性都会比正则好。
我们在前面表单验证的小节里已经接触过正则处理,我们利用了正则表达式来匹配输入的信息是否和相应的格式匹配。在使用中我们需要注意一点所有的字符都是UTF-8编码的。接下来让我们更加深入的来理解Go语言的`regexp`包。
如果你还记得,在前面表单验证的小节里,我们已经接触过正则处理,在那里我们利用了它来验证输入的信息是否满足某些预设的条件。在使用中需要注意一点就是:所有的字符都是UTF-8编码的。接下来让我们更加深入的来学习Go语言的`regexp`相关知识吧
##通过正则判断是否匹配
`regexp`包中含有三个函数用来判断是否匹配如果匹配返回true否则返回false
@@ -25,7 +25,7 @@ Go语言标准包里面已经包含有`regexp`,实现了正则表达式的搜
return true
}
我们可以看到,`regexp`的pattern和我们平常使用的正则一模一样。接下来我们再来看一个例子用户输入一个字符串,我们想知道是不是合法输入:
可以看到,`regexp`的pattern和我们平常使用的正则一模一样。再来看一个例子:当用户输入一个字符串,我们想知道是不是一次合法输入:
func main() {
if len(os.Args) == 1 {
@@ -38,12 +38,12 @@ Go语言标准包里面已经包含有`regexp`,实现了正则表达式的搜
}
}
通过上面的一些例子,我们了解到如果要判断一些字符串是否符合我们的描述需求我们采用Match(Reader|String)来进行判断,这个使用非常方便。
上面的两个小例子中,我们采用Match(Reader|String)来判断一些字符串是否符合我们的描述需求,它们使用起来非常方便。
##通过正则获取内容
我们发现采用上面Match模式只能用来作为做字符串的判断,而无法截取字符串的一部分,或者过滤字符串、或者符合条件的一批字符串。如果想要使用这些,那就需要使用正则表达式的复杂模式。
Match模式只能用来字符串的判断,而无法截取字符串的一部分过滤字符串、或者提取出符合条件的一批字符串。如果想要满足这些需求,那就需要使用正则表达式的复杂模式。
我们经常需要一些爬虫程序,下面我们就以爬虫例来说明如何过滤截取抓取的数据:
我们经常需要一些爬虫程序,下面就以爬虫例来说明如何使用正则来过滤截取抓取的数据:
package main
@@ -64,6 +64,7 @@ Go语言标准包里面已经包含有`regexp`,实现了正则表达式的搜
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("http read error")
return
}
src := string(body)
@@ -91,7 +92,7 @@ Go语言标准包里面已经包含有`regexp`,实现了正则表达式的搜
fmt.Println(strings.TrimSpace(src))
}
上面的演示代码我们可以看出,使用复杂的正则首先调用CompileCompile会解析正则表达式是否合法如果正确那么就会返回一个Regexp然后可以在任意的字符串上面应用相应的函数进行过滤、截取等操作。
从这个示例可以看出,使用复杂的正则首先Compile会解析正则表达式是否合法如果正确那么就会返回一个Regexp然后可以利用返回的Regexp在任意的字符串上面执行需要的操作。
解析正则表达式的有如下几个方法:
@@ -100,9 +101,9 @@ Go语言标准包里面已经包含有`regexp`,实现了正则表达式的搜
func MustCompile(str string) *Regexp
func MustCompilePOSIX(str string) *Regexp
Compile和CompilePOSIX不同就是POSIX必须使用POSIX语法然后他使用最左最长方式搜索而Compile是采用最左方式搜索(例如[a-z]{2,4}这样正则在搜索的时候可能搜索到任意的字母组合,那么他搜索满足条件的最左边最长的那个匹配,"aa09aaa88aaaa",当搜索这个字符串的时候,应该是返回aaaa不是第一个匹配的而Compile的返回aa最左边最先匹配的字符串)。前缀有Must的表示在解析正则语法的时候调用该函数如果解析正则语法出错直接抛出panic而不加的则返回错误。
CompilePOSIX和Compile的不同点在于POSIX必须使用POSIX语法使用最左最长方式搜索而Compile是采用的则只采用最左方式搜索(例如[a-z]{2,4}这样一个正则表达式,应用于"aa09aaa88aaaa"这个文本串时CompilePOSIX返回aaaaCompile的返回的是aa)。前缀有Must的函数表示,在解析正则语法的时候,如果匹配模式串不满足正确的语法则直接panic而不加Must的则只是返回错误。
在了解了如何新建一个Regexp之后我们来看这个struct哪些方法可以让我们操作字符串,首先我们来看下面这写用来搜索的函数:
在了解了如何新建一个Regexp之后我们来看一下这个struct提供了哪些方法来辅助我们操作字符串,首先我们来看下面这写用来搜索的函数:
func (re *Regexp) Find(b []byte) []byte
func (re *Regexp) FindAll(b []byte, n int) [][]byte
@@ -189,7 +190,7 @@ Compile和CompilePOSIX不同就是POSIX必须使用POSIX语法然后他使用
fmt.Println(submatchallindex)
}
我们前面介绍过匹配函数,那么Regexp对象也有这三个函数,和上面外部的三个函数功能一模一样,上面三个外部函数其实内部实现就是调用了这三个函数
前面介绍过匹配函数Regexp也定义了三个函数,它们和同名的外部函数功能一模一样,其实外部函数就是调用了这Regexp的三个函数来实现的
func (re *Regexp) Match(b []byte) bool
func (re *Regexp) MatchReader(r io.RuneReader) bool
@@ -227,7 +228,7 @@ Compile和CompilePOSIX不同就是POSIX必须使用POSIX语法然后他使用
fmt.Println(string(res))
}
至此我们已经全部介绍完Go语言的`regexp`包,通过上面对他的每个函数介绍以及通过例子来演示大家应该能够通过Go语言的正则包进行基本一些正则的操作了。
至此我们已经全部介绍完Go语言的`regexp`包,通过对它的主要函数介绍演示,相信大家应该能够通过Go语言的正则包进行一些基本的正则的操作了。
## links