一直以来,遇到正则表达式的时候,我更多的时候是在网上直接查找,通俗的说就是吃等食,等着直接吃别人嚼好的馍,最终的结果无疑就是谁嚼了谁才能真正吸收营养,以致于我每次再用到它时原本以为了如指掌却终止于似曾相识。 所以,简单做下归纳,增加一下理解。
在这里先贴出一篇参考资料:正则表达式30分钟入门教程:
一.正则表达式基础
1.概念:正则表达式描述了一种字符串匹配的模式,可以用来检查一个串是否有某种子串,并将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
2.正则表达式全部符号的解释
3.属性
(1)global属性:这个属性指明在搜索字符串时是全局匹配还是只匹配第一个。
(2)ignoreCase属性:指明模式搜索是否区分大小写。
4.向后引用
应用正则表达式的时候,如果想在相邻位置重复某个字符,我们通常使用下面例子这种方法:
var reg = /\d{ 2,4}/;//重复单个字符var reg = /(\d[a-z]){ 2,4}/;//重复某个字符串
当要匹配的字符串不相邻时,应该用后向引用。
说明:后向引用能够实现归功于正则表达式一个重要的特性,就是将匹配成功的模式的某部分进行存储,供以后使用。也就是说,正则表达式能够将子模式(也就是圆括号括起来的部分)存储到一个临时的缓冲区,并为它们从左到右按顺序设置编号,这些编号从1开始,2,3,4,,,以此类推。当这些缓存区的子模式被后面引用时,就会重复搜索前面存储的文本,所以后向引用实际上就是引用匹配的分组。对于有的时候,只想进行分组,而不想引用,则可以用"(?:exp)"的形式,既不匹配文本,也不引用编号。如:
var reg = /(\w{3})(?:\d+)([a-z]{2})\2/;var str = "man78abab";console.log(reg.test(str));//trueconsole.log(RegExp.$2);//ab
上面例子中:上面例子中\2匹配的不是78,而是ab就是因为第二个分组不匹配文本,也不引用编号,所以(\w{3})对应\1,([a-z]{2})对应\2;
注意1:正则对象中后向引用时只能通过\n这种方式实现,不能通过$n这种方式实现,在js中可以应用RegExp.$n这种方式查看子模块的值,另一种使用$n的方式是:
例子1: var reg = /(\d+)=(\w+)/;var str = "777=hate";console.log(str.replace(reg,'$2=$1'));//hate=777 例子2:
var str = '2013-6-7'; var re = /(\d+)(-)/g; str = str.replace(re,function($0,$1,$2){ console.log($0);//第一次是2013- 第二次是6- console.log($1);//第一次是2013 第二次是6 console.log($2);//第一次是- 第二次是- return $1 + '.'; //分别返回2013. 6. }); console.log( str ); //2013.6.7
其他分组语法:
5.次序、贪婪和懒惰
如果有这样一个表达式:a.*b,它将会匹配最长的以a开始,以b结束的字符串,如果用它来搜索aabab的话,它会匹配整个字符串aabab,也就是说,默认情况下,正则表达式中包含能接受重复的量词,它通常会匹配尽可能多的字符,这称为贪婪匹配。如果想匹配尽可能少的字符,就要进行懒惰匹配,实现的方式,就是在表示次数的字符(如:* + ? {n,m} {n,})后面加 "?"。
一点说明:
var str = 'goooogle‘;var reg1 = /o+/; //"goooo"var reg2 = /o+?/; //"go"
改动之后:
var str = 'goooogle‘;var reg1 = /o+gle/; //"oooogle"var reg2 = /o+?gle/; //"oooogle"
后面的例子中,/o+?gle/没有匹配到"ogle",是因为正则表达式中总是从左往右进行匹配,不会从右边获取子串进行匹配。
虽然上述结果相同,但是匹配的实现过程不同,在reg1中,首先o+会匹配所有的"o",然后接着匹配"gle",从而完成整体匹配。而在reg2中,o+?会先匹配一个"o",然后gle在字符串的第2位到第4位(即原串的"ooo")匹配失败。进而回溯至o+?去匹配第二个"o",成功后再在第3位到第4位匹配"gle",以此类推……最后匹配到整个字符串。
从优先级来说,从左往右的次序匹配 > 贪婪 / 懒惰匹配。
6.位置指定
接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们用于指定一个位置,就像\b,^,$那样,因此它们也被称为零宽断言。例如:
(?=exp)也叫零宽先行断言,它匹配文本中的某些位置,这些位置的后面能匹配给定的后缀exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如果在查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽后行断言,它匹配文本中的某些位置,这些位置的前面能给定的前缀匹配exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
负向位置指定
零宽负向先行断言(?!exp),只会匹配后缀exp不存在的位置。\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字。
同理,我们可以用(?<!exp),零宽负向后行断言来查找前缀exp不存在的位置:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字(实验时发现错误?注意你的“区分大小写”先项是否选中)。
7.方法,区别、联系、返回值、作用对象
(1).regObj.test(strObj);
用途:用于测试字符串参数中是否存在表达式模式,返回值:boolean(2).regObj.exec(strObj);用途:方法用于正则表达式模式在字符串中运行查找,如果找到了匹配文本,就返回一个结果数值,否则,返回null;(3).strObj.search(regObj);用途:在字符串中搜索符合正则的内容,搜索到就返回出现的位置(位置从0开始计算,如果匹配到多个,只会返回第一个的位置),搜索失败返回-1;(4).strObj.match(regObj);用途:在字符串中搜索符合规则的内容,搜索成功就返回内容,当全局匹配时:格式为数组,失败就返回null;不是全局匹配时,只匹配第一个就会停止;(5).strObj.replace(regObj,新的字符串/回调函数); 说明:第一个参数指的是每次匹配成功的字符。用途:查找符合正则的字符串,找到了就替换成对应的字符串,然后返回替换后的内容。