【转】正则表达式
上一篇文章基本没人顶。再写一篇。初学者坚持看完,准保再也不怕正则表达式。
先说两个问题。
1.正则表达式有啥作用?
查询和替换
2.什么叫做某个正则表达式匹配一个字符串?
匹配的意思是说字符串有部分字符满足正则表达式的规则。
比如/b/匹配字符串abc。/b/是个正则表达式,以斜杠开始和结束,表示的意思是 我要匹配的字符串里面有个b
下面以例子来说说正则表达式,这里不会列出每个符合表示啥意思的清单的。百度一大把啊。
案例:小写字母 /^[a-z]+$/
分析:要看懂这个表达式,得一个个分析每个符号的意思。
1.首先看看和$是意思,表示开头,$表示结尾的意思。因此/^ab/的意思是匹配以ab字母开头的字符串(准确的说应该是匹配首先是开头,第一个字符是a,下一个字符是b的字符串,请记住这种理解方式,会减少以后的误区一定要一个一个看。下面的例子分析我都会用这种方法。)。如:匹配abc,不匹配cabf。/bc$/的意思是匹配某个位置字符是b,下一个字符是c,然后是结束的字符串,如,匹配32bc,不匹配abcf。
2.再看看[]的意思,这是字符组的概念。啥意思呢,比如如果我要匹配字符串ab和ac用一个正则怎么写呢,好办,写成/a[bc]/。[bc]的意思任选其一个的意思,b也行,c也行。再来看看怎么解析/a[bc]/。匹配某个位置开始是a,然后下个字符是b或者c的字符串。
接下来再看看例子中[a-z],是abcd....z所有小写字符的字符组的简写形式。那么[2-5]其实就是[2345]的意思。哦,原来如此。这里我友情提示一下,要把[]它始终当成一个单位处理。
3.最后再来看看+是啥意思,是表示1个或者多个意思。举例说明,/a+/,表示匹配某个位置开始是a,然后接下来可能连续仍是a的字符串。比如,匹配a,aac,bac,caad。那/a+b/呢,匹配ab,aabc,aaaaab,不批配dacb。这里再一次强调。看正则一定一个一个字符的看。
那/[acb]+/,匹配a、b、c、ababf、eacf。意思很简单就是说字符串里只要有a或b或c任意一个字符就行了。而/^[ab]+$/,匹配a、b、ab、aab,但不匹配abc。因为,正则表示的意思是重复完a或b后应该就结束了。abc这个字符串重复完后是c,换句话说没有以a或b结尾。类似+这种元字符之外,还有?和。?表示0个或者一个,表示任意多个。
到现在为止,应该能看懂这个案例了。/^[a-z]+$/的意思是匹配这样一个字符串,开头、a到z的小写字母任何一个,然后重复,然后是结尾。没错就是匹配所有字符都是小写字母的字符串的意思。哎呀妈,真费劲。
如果看到这里,说明你已经接触正则30%了。
案例:大写字母 /^[A-Z]+$/
分析:略
案例:字母 /^[A-Za-z]+$/
分析:/[2-5a-e]$/等价于/[2345abcde]$/.应该触类旁通了,[a-zA-Z0-9]表示啥应该也能看得懂了。
案例 :正整数 /^[1-9]\d$/
分析 :这里出现几个新东西我们来看看
1.跟+类似,表示任意多个,可以没有。
2.这里还出现了个\,其实是\d,表示啥呢,其实是[0-9]字符组的简写形式。同样的还有\w是[a-zA-Z0-9]的意思,\s表示任意空白符
这时再来看案例,首先以1-9中某位数字开头,然后下一位是任意多个数字。自然是正整数
案例:正数 /^[1-9]\d|0$/
分析:
|表示或的意思。/a|b$/匹配字符串a、b。或和字符组看起来很像,其实不是一个概念。如/123|456$/匹配的是字符串123或者456,是不是等价于/^[14][25][36]$/这个呢,其实是不对的,因为后者也能匹配423.
现在可以看懂案例了,[1-9]\d|0分成两部分[1-9]\d* 和0。这个正则首先匹配0然后是正整数部分。自然是正数。
能不能写成下面形式呢?/\d+$/或者/[0-9]+$/。如果你认为002也算整数的话,也没问题。
案例:负整数 /^-[1-9]\d$/
分析:加个-号,自然就是负整数了。这里解答一下一个疑问。你说我就要看字符串有没有怎么办,因为在正则里是有特殊意义的。这种特殊字符被叫做元字符,犀牛书,已经终结好了,如下^$.+?!:|/()[]{}要匹配这些字符要在其前面加上\进行转义比如/^*$/来匹配*。注意上面那些特殊字符是没有引号和下划线的。还有个问题如果我就要匹配1、9、-减号怎么办?字符组不能写成[1-9],要写成[-19]这样的。
案例:负数 /^-[1-9]\d*|0$/
分析:略
案例: 整数 /^-?[1-9]\d$/
分析: ?表示一个或者0个,意思说前面的-可以没有的。你说我如果也认为+20也是正数可不可以呢。这么使用,/^[-+]?[1-9]\d$/.
案例:正浮点数 /^[1-9]\d.\d|0.\d[1-9]\d$/
分析:因为或的关系先划分成两部分,[1-9]\d.\d 和 0.\d[1-9]\d。先看最后一部分,表示匹配这样的字符串0.12。先找到.表示字符串“点”,因为.是元字符必须加\前缀来转意。0.\d[1-9]\d可以分析成: 0,然后.然后任意个非0数字。而[1-9]\d.\d自然可以理解了。
案例 : 负浮点数 /^-([1-9]\d.\d|0.\d[1-9]\d)$/
分析 : 终于出现()了。括号作用之一就是提供子表达式作用。可以看做成一个整体。上个案例如果你愿意的话,可以写成/^([1-9]\d.\d)|(0.\d[1-9]\d)$/
案例: 非负浮点数 /^[1-9]\d.\d|0.\d[1-9]\d|0?.0+|0$/
分析:跟正浮点数表达式的区别,是多了两个或。0?.0+和0,后一个自然不用说。前一个匹配0.0000,也匹配.000这种形式的
案例 : 非正浮点数 /^(-([1-9]\d.\d|0.\d[1-9]\d))|0?.0+|0$/
分析:略。
案例: 浮点数 /^([+-]?)\d*.\d+$/
分析 : 可以有加减号,然后是任意个数字,然后是.,然后至少是一个数字。注意匹配-.1这种小数的。
案例: 颜色 /^#[a-fA-F0-9]{6}$/
分析:终于出现{},{6}重复6次。如果写成{1,2}表示重复1到2次。如果写成{1,}表示至少一次,也就是+。同理{0,}是*,{0,1}是?
颜色取值是16进制的。自然匹配ffffff,白色哈。注意也匹配这种的BBaaCc。
案例:日期 /^\d{4}(-|/|.)\d{1,2}\1\d{1,2}$/
分析:这个表达式,也能匹配这种的0000-2-2。你可以优化。这里拿这个代码主要说的事情是什么呢?你一个个字符读下来。却发现有个\1不认识。这就是要说的()的三大作用(选择、分组和引用)中的引用。\1表示引用表达式中的第一个括号。
读读先,再理解。首先是四位数字,然后是-或\或.,然后1到2位数字,然后是前面用过的那个符号比如是-,然后1到2位数字。
如果你把\1换成前面那个,表达式成/^\d{4}(-|/|.)\d{1,2}(-|/|.)\d{1,2}$/,其实也能匹配0000-2.1了显然就不对了。要么都-,要么都用.或/。
案例:身份证 /\d{17}[\d|x]|\d{15}/
分析:只是简单的判断18位和15位的。有的18位身份证最后一位是x也判断了一下。准确的来说这只是一个初步判断。一位18个0的身份证毕竟是没有的。考虑复杂的话,这个正则得写老长了。
案例:手机 /0?(13|14|15|18)[0-9]{9}/
分析:easy,我以前写判断手机直接就11位然后1开头的。
案例:密码 /^[A-Za-z0-9_-]+$/
分析:字母数字连字符合下划线,当然你可以加上位数限制。
案例: 邮政编码 /\d{6}/
分析:略
案例: 图片 /(.).(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$/
分析:我不写你也能看出来它是干什么的。这里里面终于用到元字符.了。表示换行符之外的任意字符。注意能匹配.jpg,最好把前面的改成+。
案例:压缩格式 /(.*).(rar|zip|7zip|tgz)$/
分析:略。
案例:中文 /^[\u4e00-\u9fa5]+$/
分析:\uxxxx表示16进制unicode字符。什么回车符,制表符自己找个资料看吧。如/^[\x00-\xFF]+$/表示仅ACSII字符
案例:非空 /^\S+$/
分析:终于遇到个非开头的。\s表示匹配空白符的。换成大写的\S表示,非空白符的字符。注意首先它是个字符。然后不是空白符。
同样也有\D表示非数字等价于[0-9]。这是字符组的取非表示方式。如[ab]表示除a和b之外的任意字符。注意他是个字符。
案例:ftp /ftp://[:]*:@([/]*)/
分析:写的比较粗略。匹配ftp://1111:@aaa/ 。注意在字符组里元字符是不需要加\的。
案例:ip地址 /((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d).){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))/
分析:略。给你当做作业来分析吧。自己调查资料去吧。(?: )这个东西是表示只当括号用,排除引用功能。上述案例你可以换成()。
案例:email /\w+((-w+)|(.\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+/
分析:作业。注意\w表示[a-zA-Z0-9]
最后总结一下,本文以一个个例子把正则说个七七八八。求顶啊。
能坚持看下来,回头再去看看书,会轻松很多的。写和看是两回事,以后再看正则时,多难的都敢去分析了。
本文完。