JS正则表达式总结
//RegExp有以下两个方法
//test():返回模式是否匹配
//exec():返回一个数组,第一个是匹配项,后边依次是分组匹配项,如果分组匹配不成功,则为undefined。而且还返回属性index(匹配项起始index),input(要验证的字符串)
var rExec=/mufc(\d)/g; var sExec="amufc1 sssmufc2 wwmufc3 ss"; console.log(rExec.exec(sExec));//["mufc1", "1"] console.log(rExec.exec(sExec));//["mufc2", "2"] console.log(rExec.exec(sExec));//["mufc3", "3"]
//String对象有以下两个方法:
//match():返回包含在字符串中的所有匹配的数组
//search():返回在字符串中出现的一个匹配位置
var rMatch=/mufc(\d)/g; var sMatch="amufc1 sssmufc2 wwmufc3 ss"; console.log(sMatch.match(rMatch));//["mufc1", "mufc2", "mufc3"] var rSearch=/mufc(\d)/g; var sSearch="amufc1 sssmufc2 wwmufc3 ss"; console.log(sSearch.search(rSearch));//1
//简单模式
//元字符 元字符是正则表达式的一部分,若要匹配,必须转义,元字符有:{[(\^$|))?*+.
var r1=/\?/; var s1="?"; console.log(r1.test(s1));
//字符类用于测试字符的组合,通过将字符放入方括号中,可以匹配其中之一
var r2=/[ab]o/g;
var s2="aocsrwgoboao";
console.log(s2.match(r2));
//字符类之负向类,它可以指定要排除的字符
var r3=/[^ab]o/g;
var s3="aocsrwgoboao";
console.log(s3.match(r3));
//范围类:[a-z][A-Z][0-9] 以上几种还可以组合:
var r4=/[a-z1-4\n]/g;
var s4="39r\n8";
console.log(s4.match(r4));
//预定义类:.代表[^\n\r] 除了换行和回车之外的任意字符
//\d [0-9] 数字
//\D [^0-9] 非数字
//\s 空白字符
//\S 非空白字符
//\w [a-zA-Z_0-9] 单词字符(所有字母数字下划线)
//\W [^a-zA-Z_0-9] 非单词字符
//量词 指定某个特定模式的出现次数
//? 0此或一次
//* 零次或多次
//+ 一次或多次
//{n} 一定出现n次
//{n,m} n到m次
//{n,}至少n次
//贪婪量词:先看整个字符串是否匹配,如果没有匹配,去掉字符串最后一个字符再次尝试,如果还没匹配,再去掉最后一个字符,一直到最后一个字符或不剩下字符。只使用一个量词是贪婪。
//惰性量词:先看第一个,如果不匹配,就读下一个字符,组成两个字符的字符串,直到匹配成功或整个字符串都未匹配成功。一个量词后再跟一个?即是惰性量词。
//支配量词:只尝试匹配整个字符串,只有这一步,不成功就停止匹配。一个量词后跟一个+就是支配量词。
var r5=/(.*abc)/g;
var r6=/(.*?abc)/g;
var r7=/(.+abc)/g;
var s7="dabcsecdabc";
console.log(r5.test(s7));
console.log(RegExp.$1);
console.log(r6.test(s7));
console.log(RegExp.$1);
console.log(r7.test(s7));
console.log(RegExp.$1);
//分组:用括号包含一系列字符,字符类以及量词
//反向引用:表达式计算完以后,每个分组存放在一个特殊值,这个特殊值就是反向引用。反向引用是按照从左到右遇到的左括号的顺序来创建和编号的。通过方法test(),exec(),match(),search()后,反向引用值可以从RegExp构造函数中获得。
var r8=/#(\d+)/;
var s8="#12345";
r8.test(s8);
console.log(RegExp.$1);
r8.exec(s8);
console.log(RegExp.$1);
s8.match(r8);
console.log(RegExp.$1);
s8.search(r8);
console.log(RegExp.$1);
//使用转义序列\1 \2 \n可以直接在定义分组的表达式中包含反向引用。
var r9=/(my)\1/;
var s9="mymy";
console.log(r9.test(s9));
//候选:使用管道符|,把它放在两个单独的模式之间可以实现匹配其一的效果。
var r10=/fuck|shit/gi;
var s10="no say fuck or shit";
console.log(s10.replace(r10,"*"));
//非捕获性分组:不会创建反向引用的分组,使用方式:在左括号的后面加上一个问号和冒号
var r11=/#(?:\d+)/;
var s11="#12345";
r11.test(s11);
console.log(RegExp.$1);
//前瞻:正则表达式运算器向前看一些字符而不移动其位置,正向前瞻检查接下来是不是某个特定字符集,负向前瞻检查接下来不应该出现的特定字符集。正向用(?=)负向用(?!),前瞻不是分组!
var r12=/(b(?=a))/;
var r13=/(b(?!a))/;
var s13="ba";
console.log(r12.test(s13));
console.log(r13.test(s13));
//边界:^ 行开头 $ 行结尾 \b 单词边界 、B非单词边界
var r14=/\b(\S+?)\b/g;
var s14="i love you";
console.log(s14.match(r14));
//多行模式:会让$边界匹配符匹配换行符\n以及真正的结尾。
var r15=/(\w+)$/g;
var r16=/(\w+)$/m;
var r17=/(\w+)$/gm;
var s17="i am\n a football\n fan";
console.log(s17.match(r15));//["fan"]
console.log(s17.match(r16));//["am","am"]
console.log(s17.match(r17));//["am","football","fan"]
//javascript中,每个正则表达式都是一个对象。RegExp的实例有一些我们可以访问的属性 global 表示g是否已设置 ignoreCase 表示i是否已设置 lastIndex 代表下次匹配会从哪个字符开始 multiline 表示m是否已设置 source 正则表达式的源字符串形式
var r18=/b/g;
var s18="abcdedabeeadbsa";
r18.exec(s18);
console.log(r18.lastIndex);
r18.exec(s18);
console.log(r18.lastIndex);
//静态属性:静态的RegExp属性对所有正则表达式都有效,这些属性都有两个名字,一个复杂名字,一个以美元开头的简短名字。
//长名 短名 描述
//input $_ 最后用于匹配的字符串
//lastMatch $& 最后匹配的字符
//lastParen $+ 最后匹配的分组
//leftContext $" 在上次匹配的前面字符串
//multiline $* 指定是否所有的表达式都是使用多行模式的布尔值 并非所有浏览器都支持
//rightContext $' 在上次匹配之后的字符串
//这些属性可有告诉你使用exec() test()完成的匹配的一些特定的信息
var r19=/h(i)/g;
var s19="this is a test haha";
r19.test(s19);
console.log(RegExp.input);//this is a test haha
console.log(RegExp.leftContext);//t
console.log(RegExp.rightContext);//s is a test haha
console.log(RegExp.lastMatch);//hi
console.log(RegExp.lastParen);//i
运行结果:
最后总结下exec和match的用法与差别:
var sMatch="amufc1 sssmufc2 wwmufc3 ss"; var r=rExec=/mufc(\d)/; var rr=/mufc(\d)/g;
没有g时:
可以看到匹配的结果没有区别。
对于有g时:
match返回全部匹配结果,但是不包括捕获分组部分
exec则每次返回一个结果,同时lastindex值也会改变,当继续执行时,就从当前的lastindex开始匹配接下来的匹配项