轻松理解正则表达式

本文是帮助刚接触正则表达式的童鞋理解的,主要描述了正则表达式是个什么东西,而不是讨论用法和工作原理。不过也欢迎高手批评指正,以更好的帮助新手


正则表达式曾是我学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解释器强大。


说明:本文章纯属个人观点,不保证绝对正确,欢迎大家批评和指正,同时我自己也会对本文不断的更新和完善。


转载于:https://my.oschina.net/yanquan345/blog/202285

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值