本文是帮助刚接触正则表达式的童鞋理解的,主要描述了正则表达式是个什么东西,而不是讨论用法和工作原理。不过也欢迎高手批评指正,以更好的帮助新手。
正则表达式曾是我学Shell时最头大的一个问题,当时总以为他是条命令啥的,显然他不是,也显然是个表达式,那什么叫表达式呢,这个概念先不管,应该都听说过算术表达式吧,那算术表达式是啥呢,怎么描述呢,在数学课程中是这样描述的:由数字和运算符号组成的式子,可以简单清晰地记录或描述计算过程和内容【摘自百度百科】,我们只看前半句,说明是个式子,式子都知道吧,简单的说是一句话,有特定含义的一句话,当然编程语言中的算术表达式还是个式子,正则表达式也是个式子。
现在知道它也是一种表达式了,那他是干嘛用的呢?算术表达式是用于描述计算过程和内容的,正则表达式主要是用于匹配字符串的,这个表达式就是描述了一批而不是一个字符串,如果另一个字符串属于这一批字符串,就可以说该字符串与该正规表达式匹配成功。那这个一批哪底包含哪些呢,先举个不是正则表达式的简单例子,通配符都知道吧,不知道的也见过这样的表达式吧:
*.c
*.java
分别表示所有以“.c”和以“.java”为后辍的,虽然大部分都见过,我们还是做个小实验:
elwin@Ubuntu64:~/work$ ls
1.c 1.java 2.c 2.java 3.c file1.txt
elwin@Ubuntu64:~/work$ ls *.c
1.c 2.c 3.c
elwin@Ubuntu64:~/work$ ls *.java
1.java 2.java
当我们调用“ls”显示文件的时候,全部显示了,使用“ls *.c”则只显示了所有c文件,而“ls *.java”则显示了所有java文件,这是因为星号“*”被Shell扩展了(注意不是被ls扩展,传给ls命令的已经是扩展好的数组了),我们写个脚本打印所有输入参数来验证一下,
#!/bin/sh
echo "$*"
(其中“$*”是指代所有输入参数)输出结果是:
elwin@Ubuntu64:~/work$ ./test.sh *.c
1.c 2.c 3.c
在这里*.c代表了一批字符串,而这一批字符串包含了“1.c 2.c 3.c”,所以它们匹配成功了。不过这不是正则表达式,但思想是一样的,就是其中有的字符有特殊含义,当然这个特殊含义是相对就言的,例如上面的星号“*”对你而言就是星号,但对Shell而言,星号代表任意字符串。正规表达式与通配符就语法和符号代表的特殊含义是不同的,正规表达式的表达能力要强大得多,你可以认为正则表达式是通配符升级版,其实正则表达式是一种计算机的一个重要理论,它被应用于编译器的词法分析,跟有穷自动机有重要的联系,关于历史,先不讨论了。与上面的等价的用正则表达式是这样的:
.*\.c
暂时看不懂没关系,下面慢慢解释,我们先用sed试一下吧:
elwin@Ubuntu64:~/work$ ls |sed -n '/.*\.c$/p'
1.c
2.c
3.c
用斜杠里面包括的(不含斜杠)就是一个正则表达式,(这条组合命令你不知道没关系,你只要知道他的作用是:显示当前目录下,文件名符合该正则表达式的文件)。下面解释一下这个正则表达式,其中的点“.”代表任意字符,星号“*”表示将前面的那个字符重复n次(包括0次),这两个的意思就是将任意字符重复篇,如果正则表达式就这两个,后面不写了,那就表示世上所有字符串,我们再试一下吧:
elwin@Ubuntu64:~/work$ ls |sed -n '/.*/p'
1.c
1.java
2.c
2.java
3.c
file1.txt
test.sh
看吧,所有文件都列出来了,说明都匹配成功了。现在我们继续分析刚刚的表达式,星号后面的反斜杠表示转义,即把接下来的那个字符(这里是点号)当作普通字符,没有特珠含义,如果不在前面加上反斜杠就代表任何字符了,接下来的“c”在正则表达式里属于普通字符串,再接下来的美元符“$”表示换行符,于是整个表达式的意思就是:任意长度的字符串,连上“.c”,再接一个换行符,如果不接这个换行符,那“1.cc”也会被匹配,如:
elwin@Ubuntu64:~/work$ touch 1.cc
elwin@Ubuntu64:~/work$ ls |sed -n '/.*\.c/p'
1.c
1.cc
2.c
3.c
你可能有个疑问,哪到到底算特珠符号,哪些算普通符号呢,这当然有个规定了,这此特殊符号都有各自的含义,这种文章网上很多,大家可以搜索,也可以看man手册(man grep就可以),也可以参考此文,本文主要目是帮助初学者理解正则表达式,而不是讨论详细用法。
还有一点需要说明,Shell、Java、Perl都有正规表达式,不过他们之间只有细微的区别,很多都是通用,其中以Perl中的正则表达式最强大,原因是Perl解释器强大。
说明:本文章纯属个人观点,不保证绝对正确,欢迎大家批评和指正,同时我自己也会对本文不断的更新和完善。