正则表达式-简介与基本语法
正则表达式#
简介#
在前面的案例中,我们已经完成了将网页的内容进行爬取,并且进行保存。但是,我们并没有对获取的网页数据内容进行筛选,而直接全部保到文件中了。
那如何对爬取到的网页内容进行筛选提取呢?之前学过的 string 包中的一些字符串操作函数可以完成这类任务,如:搜索 (Contains、Index)、替换 (Replace) 和解析 (Split、Join),但是处理网页数据实现起来相对而言复杂度较高。实际在工作中,对于这类字符串拆分提取操作,我们通常使用正则表达式来实现。通过正则表达式提取网页内容要方便许多。
当然如果 strings 包提供的函数能解决你的问题,那么就尽量使用它来解决。因为他们足够简单、而且性能和可读性都要比正则好。
正则表达式是一种进行模式匹配和文本操纵的复杂而又强大的工具。虽然正则表达式比纯粹的文本匹配效率低,但是它却更灵活。按照它的语法规则,随需构造出的匹配模式就能够从原始文本中筛选出几乎任何你想要得到的字符组合。
对于初学正则表达式的学者,最困难的地方就是它语法中繁多杂乱的符号。所以大多数工作者,都在记忆中保存正则表达式的整体规范,而做不到完全记忆。确保自己手边有一套可靠的正则查找资料,或者能保证随时上网查询即可。对于正则的语法,这里我们捡常用的一些,加以分类介绍:
基本语法#
以前我们用 grep 在一个文件中找出包含某些字符串的行,比如在头文件中找出一个宏定义。其实 grep 还可以找出符合某个模式(Pattern)的一类字符串。例如找出所有符合 xxxxx@xxxx.xxx 模式的字符串(也就是 email 地址),要求 x 字符可以是字母、数字、下划线、小数点或减号,email 地址的每一部分可以有一个或多个 x 字符,例如 abc.d@ef.com、1_2@987-6.54,当然符合这个模式的不全是合法的 email 地址,但至少可以做一次初步筛选,筛掉 a.b、c@d 等肯定不是 email 地址的字符串。再比如,找出所有符合 yyy.yyy.yyy.yyy 模式的字符串(也就是 IP 地址),要求 y 是 0-9 的数字,IP 地址的每一部分可以有 1-3 个 y 字符。
如果要用 grep 查找一个模式,如何表示这个模式,这一类字符串,而不是一个特定的字符串呢?从这两个简单的例子可以看出,要表示一个模式至少应该包含以下信息:
字符类(Character Class):如上例的 x 和 y,它们在模式中表示一个字符,但是取值范围是一类字符中的任意一个。
数量限定符(Quantifier): 邮件地址的每一部分可以有一个或多个 x 字符,IP 地址的每一部分可以有 1-3 个 y 字符。
各种字符类以及普通字符之间的位置关系:例如邮件地址分三部分,用普通字符 @和。隔开,IP 地址分四部分,用。隔开,每一部分都可以用字符类和数量限定符描述。为了表示位置关系,还有位置限定符(Anchor)的概念,将在下面介绍。
规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。例如 email 地址的正则表达式可以写成 [a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+.[a-zA-Z0-9_.-]+,IP 地址的正则表达式可以写成 [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}。下一节介绍正则表达式的语法,我们先看看正则表达式在 egrep 中怎么用。例如有这样一个文本文件 regexp_test.txt:
192.168.1.1
1234.234.04.5678
123.4234.045.678
abcde
$ egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' regexp_test.txt
192.168.1.1
1234.234.04.5678
egrep 相当于 grep -E,表示采用 Extended 正则表达式语法。书写测试时,注意不要省略 ‘ ‘
字符类:#
数量限定符:#
注意 egrep 找的是包含某一模式的行,而不是完全匹配某一模式的行。
例如有如下文本:
aaabc
aad
efg
查找 a * 这个模式的结果。会发现,三行都被找了出来。
$ egrep 'a*' regexp_test.txt
aaabc
aad
efg
a 匹配 0 个或多个 a,而第三行包含 0 个 a,所以也包含了这一模式。单独用 a 这样的正则表达式做查找没什么意义,一般是把 a * 作为正则表达式的一部分来用。
位置限定符#
位置限定符可以帮助 egrep 更准确地查找。
例如上一节我们用 [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3} 查找 IP 地址,找到这两行
192.168.1.1
1234.234.04.5678
如果用 ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ 查找,就可以把 1234.234.04.5678 这一行过滤掉了。
其它特殊字符:#
Go 语言通过 regexp(regular expression)
标准包为正则表达式提供了官方支持,如果你已经使用过其他编程语言提供的正则相关功能,那么你应该对 Go 语言版本的不会太陌生。但是它们之间也有一些小的差异,因为 Go 实现的是 RE2 标准,详细的语法描述可参考:code.google.com/p/re2/wiki/Syntax 如遇无法打开,也可参看:
推荐文章: