正则表达式

今天在 使用awk工具处理日志的时候,需要捕获ip地址进行分类,于是随手就写了一个匹配ip的正则((\d{1,3})\.){3}\d{1,3},但是在匹配的时候发现没有任何反应,仔细检查并测试之后,发现并不是我写的正则有问题,而是这是一个历史遗留问题。

正则表达式的种类

纵观整个Regular Expression(正则表达式)的历史,你就会发现,正则表达式是有一个发展过程的,像我上面写的((\d{1,3})\.){3}\d{1,3}这样的正则表达式,其实是比较现代的正则表达式,也就是Perl的正则表达式(Perl Regular Expression),简称PREs。但是在PREs出现之前,人们常用的是BREs(基础正则表达式),和EREs(扩展正则表达式)。

三种正则表达式的区别

如果单从语法的角度看,三种正则表达式并没有多大区别,都是由元字符+普通字符组成,其中元字符“ ^ $ . * + ?  ()  [] {} \ ” 这些基本的元字符都包含在内,这些元字符是正则表达式的基础,但是BREs基础正则表达式对于“* + ? () {}”的支持是需要转义才能使用的,比如在PREs中[0-9]{1,3}匹配1-3个0-9之间的数字,在BREs中的写法则是[0-9]\{1,3\}。

EREs和PREs在“ * + ? () {} ”的使用上则没有什么不同

在PREs中,我们常常使用\d \s \t \n \f \num 等等这种带有转义性质的特殊元字符,在BREs和EREs中是不 支持的

awk sed grep对三种正则表达式的支持

在linux命令行下,我们常常用的awk sed 以及grep命令,默认支持的都是BREs(基础正则表达式),不过grep带上参数之后可以提供对PREs和EREs的支持(grep -P, grep -E),如果习惯使用PREs的话,可以对grep 加上别名

alias grep = "grep -P"

解决方案

了解了三种表达式的区别以后,想要解决之前出现的问题,就非常简单了,只需要把(\d{1,3}\.){3}\d{1,3}改成(\d{1,3}\.)\{3\}\d\{1,3\},就解决了问题了。

正则表达式是一种强大的工具,我觉得任何一个程序员都应该熟练掌握它。

发表评论