第一部分 字符
part1 元字符
正则表达式的元字符有:( [ { ? \ ^ $ + * | .
对这几个元字符依次做出解释如下:
小括号()
1.小括号主要是用来划分整体的(分组)
实例一:
var reg = new RegExp(‘(test)?‘);
‘test‘.match(reg); //[‘test‘, ‘test‘] 首先以/test?/进行匹配,然后按照小括号里的/test/进行匹配
var reg1 = new RegExp(‘test?‘);
‘test‘.match(reg1); //[‘test‘]
实例二:
var reg = new RegExp(‘mon( and dad)?‘);
‘mon and dad‘.match(reg); //[‘mon and dad‘, ‘ and dad‘] 首先以整体/mon( and dad)?/匹配,然后按照小括号里的/ and dad/进行匹配
var reg1 = new RegExp(‘(mon( and dad)?)‘);
‘mon and dad‘.match(reg1); //[‘mon and dad‘, ‘mon and dad‘, ‘ and dad‘] 首先以整体模式/(mon( and dad)?)/进行匹配,然后按照外层小括号里面的/mon( and dad)?/进行匹配,最后按照最里层括号里的/ and dad/进行匹配
‘monanddad‘.match(reg1); //[‘mon‘, ‘mon‘, undefined] 首先以整体/(mon( and dad)?)/匹配,匹配到‘mon‘,然后由外面第一层括号里面的/mon( and dad)?/匹配,匹配到‘mon‘,然后由最里层小括号的/ and dad/匹配,匹配无结果
2.小括号其他的应用地方:反向捕获文本(下篇解释)
中括号[]
1.中括号是用来界定范围的
实例:
var reg = /[123]/;
对于这个正则,它的意思是可以匹配包含1到3这三个数值任意一个的字符串。
2.中括号也可以用在排除范围中
实例:
var reg = /[^123]/;
这个正则的意思是要匹配的字符串不能含有1到3这三个字符的任意一个
中括号中的范围也可以这么写,/[0-9]/,但是不能写成/[9-0]/,‘-‘两旁的字符是由ascii码从小到大的顺序写的。
大括号{}
大括号用来指定数量的
实例:
var reg = /1{4}/; //这个就是匹配1111啦
但指定数量的时候也是有一些特殊的情况,比如:
var reg = /1{4,}/; //至少连续4个1
var reg = /1{4,6}/; //4到6个1
问号?
加号 +
星号 *
这几个也是和出现次数相关的,
?表示出现0次或1次
+表示出现至少1次
*表示出现次数随便,出现0次也行,出现多次也行
幂符号^
用在两个地方,一个是取反的意思,一个是边界符号,表示开头
实例
var reg = /[^abc]/; //匹配除了abc的字符
管道符|
表示候选项
实例
var reg = /[red|black|yellow]/; //匹配red 或 black 或 yellow
英文点.
可以匹配除了换行符和回车符(\r\n)以外的任意字符
转义\
dollor符$
表示字符边界,结尾
part2 预定义的特殊字符
\t 制表符
\r 回车符
\n 换行符 windows中的文本文件用\r\n来结束一行,UNIX中用\n
part3 预定义的范围
可以用一些特殊的符号来表达字符想要匹配的范围:
. 除\r\n以外的任意字符
\d 数字
\D 非数字
\s 空白(space),具体匹配的字符和具体实现有关,大部分会匹配空格符、tab符、\n \r
\S 非空白
\w 单词字符(a-zA-Z0-9_)
\W 非单词字符
part4 边界符号
表示边界的字符有^ $ \b \B,它们的具体含义是
^ 开头
$ 结尾
\b 单词边界
\B 非单词边界
\b 单词边界(单词的含义是a-zA-Z0-9_这个符号范围内的组合,所以\b匹配到的是单词字符范围以外的字符)
单词边界不会匹配出一个字符,也就是它无返回值,它只是说明了位置。四种情况可以认为是单词的边界:
(1)字符串第一个字符为单词字符,第一个字符前面的位置。
(2)字符串最后一个字符为单词字符,则最后一个字符后的位置。
(3)单词字符与非单词字符紧挨着,它俩之间的位置。
(4)非单词字符与单词字符紧挨着,它俩之间的位置。
\B 非单词边界类似\b,也是0匹配的无返回值,只是指明了位置
实例:
var reg = /\b\w+\b/g;
"12w-eefd&efrew".match(reg); //["12w", "eefd", "efrew"]
第二部分 一些正则技巧
1.捕获--反向引用
正则表达式由小括号包裹起来的规则匹配到的值可以通过引用获取到,这就是反向引用,反向引用可以用在replace方法中,也可以用在正则表达式规则的书写中。
反向引用中的\1 \2 ..的值是从左往右的小括号依次匹配的值,也就是说分组捕获是按照正则表达式从左往右依次找寻括号来匹配的,就算有括号嵌套也如此。
实例一:匹配连续出现4次的小写字母
正则表达式可以这么写:
/([a-z])\1{3}/.test(‘aaaaa‘); //true
或者
var reg = new RegExp(‘([a-z])\\1{3}‘); //这里\1前面加了转义
reg.test(‘aaaa‘); //true
上面的正则表达式的意思是:([a-z])获得一个小写字母,\1是小写字母的值,也就是匹配aa这种,ad这种就不行了。{3}对\1重复三次。
实例二:在一个字符串中,每三个字符中间插一个空格
var formatString = function(str){
return str.replace(/(.{3})/g, ‘$1 ‘);
}
上面的正则表达式的意思是:.是除了回车和换行之外的任意字符,它重复三次,匹配到的字符存储在$1中,然后用$1加空格替换。
实例三:一个句子中每两个单词相互交换
var switchFunc = function(str){
return str.replace(/(\S+)(\s+)(\S+)/g, ‘$3$2$1‘);
}
上面正则表达式的意思是:\S匹配非空格字符,\s匹配空格字符,匹配到的值通过replace做位置交换。
2.不捕获
(1)只分组不捕获
顾名思义,我只需要实现分组,但在反向引用的输出中,我不需要这个值,这个时候可以用(?: )
实例一:
对‘10086.001$‘这样的字符串过滤,我只需要数值部分中的整数部分和货币符号 这两个输出,
var reg = /(\d+)(?:.?)(?:\d+)([$¥])/;
‘10086.001$‘.replace(reg,‘$1$2‘); //"10086 $"
(2)前向查找
具体形式是(?= ),空谈太模糊,直接上例子
实例一:
需求是这样的,我需要匹配出0-9a-z中的两个字符,并且这两个字符后面必须跟着‘aa‘,‘aa‘是不捕获的
var reg = /[0-9a-z]{2}(?=aa)/g;
‘123aatestaaoaa‘.match(reg); //["23", "st", "ao"]
当查找到23aa可以匹配的时候,下面的查找是从23aa中的aa开始匹配的,因为aa未被捕获。
(3)后向查找(js不支持)
具体形式是(?<= )
实例:
匹配出0-9a-z中的两个字符,并且字符前面必须有两个‘aa‘,并且‘aa‘是不捕获的
正则表达式可以这么写 /(?<=aa)[0-9a-z]{2}/g,但是js不支持
(4)前向查找匹配,匹配的规则是后面不跟有某某字符
具体形式是(?! )
var reg = /[0-9a-z]{2}(?!aa)/g; //查找0-9a-z的两个字符,并且这两个字符后面不跟着aa
‘123aatestaaoaa‘.match(reg); //["12", "3a", "at", "es", "ta", "oa"]
(5)后向匹配查找,匹配的规则是前面没有某某字符(js不支持)
具体形式是(?<! )
第三部分 关于正则表达式的一些js方法
主要介绍的有match test replace exec split search,其中属于字符串的方法有match replace split search,属于正则对象的方法有exec test
match
字符串方法,string.match(reg)
返回的是数组,数组的内容因正则是否配备‘g‘而不同,当reg为‘//g’的形式的时候,返回的数组是字符串所有匹配到的内容,当reg无g时,返回的是从左到右括号匹配到的内容。
例如:
var reg = /a(b+)(\d+)/g;
"abbb34eftab0modabbbbb6".match(reg); //["abbb34", "ab0", "abbbbb6"] 返回的是所有匹配到内容,忽略括号
var reg1 = /a(b+)(\d+)/;
"abbb34eftab0modabbbbb6".match(reg1); //["abbb34", "bbb", "34"] 没有global返回的就是从左到右括号匹配到的内容啦
exec
属于正则表达式的方法,RegExp.exec(string)
返回的是数组,数组内容和正则表达式中没有g时match方法返回的一样,也就是从左到右括号返回的内容
例如:
var reg = /a(b+)(\d+)/g;
reg.exec("abbb34eftab0modabbbbb6"); //["abbb34", "bbb", "34"]
var reg1 = /a(b+)(\d+)/;
reg1.exec("abbb34eftab0modabbbbb6"); //["abbb34", "bbb", "34"]
不过当正则表达式有‘g‘时,当下一次调用exec时,RegExp对象的lastIndex为上一次匹配到的字符串后紧跟的位置,所以在再次执行时,会从这个位置开始,可以循环调用exec可以得到当正则有global时match方法的结果。
var reg = /a(b+)(\d+)/g;
while( (result = reg.exec("abbb34eftab0modabbbbb6")) != null ){
console.info(result[0]);
}
输出为
abbb34
ab0
abbbbb6
test
检查字符串是否满足正则表达式,reg.test(string),能匹配到则返回true,匹配不到返回false
var reg = /\d/;
reg.test(‘abc‘); //false
reg.test(‘123‘); //true
第四部分 正则的实例
1.获取一个url后面的两级相对地址,比如“http://www.cnblogs.com/cy163/archive/2010/04/20/1715835.html”,提取出"/cy163/archive"
var reg = /(\b\/[^\/]+){2}/g;
“http://www.cnblogs.com/cy163/archive/2010/04/20/1715835.html”.match(reg); //["/cy163/archive", "/2010/04", "/20/1715835.html"]
感谢:
http://www.cnblogs.com/yakun/p/3795589.html
http://www.cnblogs.com/snandy/p/3662423.html
http://www.cnblogs.com/rubylouvre/archive/2010/03/09/1681222.html
http://dragon.cnblogs.com/archive/2006/05/09/394923.html
http://www.cnblogs.com/dragon/archive/2006/05/08/394078.html
http://www.cnblogs.com/bluedream2009/archive/2009/08/08/1541585.html