正则就是一种规则,用来处理字符串
1.判断一个字符串是否符合制定规则 test 匹配
2.把字符串中符合正则的内容捕获到 exec 捕获
1.字面量方式
var reg = /\d/;
2.实例创建
var reg = new RegExp("\d");
这两种创建方式的区别的
console.dir(RegExp.prototype);
var reg = /\d/; //包含一个0-9的数字
reg.test(str)
每一个正则表达式都是由元字符和修饰符组成的
元字符:在两个斜杠之间有意义的字符就是元字符
修饰符:全局匹配g,不区分大小写i,行首行尾m
\ :转义字符,转义后边字符所代表的含义
^ :以某个元字符开始
$ :以某个元字符结尾
^和$并不占位,当同时出现时就表示一个字符
\n:匹配一个换行符
. :除了\n以外的任意字符
var reg = /^0.2$/;
//以0开头,以2结尾,中间为除了\n的任意字符
若想只表示0.2则需要对元字符进行转义
var reg = /^0\.2$/;
():分组,把一个大正则划分为几个小正则
x|y:x或y中的一个
\d:0-9之间的数字
\D:除了0-9之间的数字,以外的任意字符
\b:一个边界符
\w:数字、字母、下划线中的任意字符 等价于[0-9a-zA-Z_]
\s:匹配一个空白字符 如:空格,制表符(tab键),换页符
"*" :出现0到多次
"+" :出现1到多次
"?" :出现0或1次
{n}:出现n次
{n,}:出现n到多次
{n,m}:出现n到m次
有效数字验证:
[]中出现的所有字符都是代表本身意义的字符,没有特殊含义
[]中不识别两位数
()分组的作用:能改变x|y的默认优先级
var reg = /^18|19$/;
var reg2 = /^(18|19)$/;
字面量方式中斜杠之间包含的所有内容都是元字符,不能进行变量拼接
var name = "abc";
var reg = /^\d+"+name+"\d+$/;
console.log(reg.test('2015"""nameee"2016'));
实例创建方式中包含的就是字符串
var name = "abc";
var reg = new RegExp("^\\d+"+name+"\\d+$");
console.log(reg.test("2015abc2016"));
//在字符串中需要对\进行转义
1.或者2-6或者8
var reg = /^[12-68]$/;
2.数字字母下划线和-
var reg = /^[\w-]$/;
3.匹配年龄18-65之间 分为18-19,20-59,60-65
var reg = /^(1[8-9]|[2-5]\d|6[0-5])$/;
4.匹配中国汉字姓名
var reg = /^[\u4e00-\u9fa5]{2,4}$/;
捕获的内容是一个数组[当前正则捕获到的内容为:index,捕获内容在字符串中起始索引;捕获的原始字符串]
若没有匹配到内容,则直接返回null
每一次捕获时都先进行默认匹配,如果没有匹配成功则返回null;只有有匹配的内容才能捕获到
var reg = /\d+/;
var str = "abcde2015fghijk2016";
var res = reg.exec(str);
console.log(res);
修饰符:g,i,m
var reg = /\d+/g;
var str = "abcde2015fghijk2016";
console.log(reg.lastIndex);//0
console.log(reg.exec(str));//["2015"...]
console.log(reg.lastIndex);//9
console.log(reg.exec(str));//["2016"...]
原理:增加全局修饰符g后,每一次捕获结束后lastIndex的值都变为了最新的值,下一次捕获从最新位置查找,这样就查找到了所有内容
var reg = /\d+/g;
var str = "abcde2015fghijk2016lmn2017";
var arr = [];
var res = reg.exec(str);
while(res){
arr.push(res[0]);
res = reg.exec(str);
}
正则的每一次捕获都是按照最长的匹配结果捕获的,例如:2,20,201,2015
如何解决贪婪性?
在量词元字符后加一个""?即可,例var reg = /\d?/g;
?作用:
1)放在普通元字符后面表示出现0或1次
2)放在量词元字符后面表示取消捕获时的贪婪性
字符串中的match方法,把所有和正则匹配的字符都获取到
var reg = /\d+?/g;
var str = "abcde2015fghijk2016lmn2017";
var arr = str.match(reg);
match存在的问题: 在分组捕获的情况下,match只能捕获到大正则匹配的内容,而对于小正则捕获的内容是无法获取的
1)改变优先级
2)分组引用
var reg = /^(\w)\1(\w)\2$/;
console.log(reg.test("zzff"));
console.log(reg.test("z0fa"));
\2代表和第二个分组出现一模一样的内容(值一样)
\1代表和第一个分组出现一模一样的内容
3)分组捕获
正则在捕获的时候,不仅把大正则匹配的内容捕获到,而且还可以把小分组匹配的内容捕获
"?:"在分组中只匹配不捕获
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/;
var str = "130180199210011234";
console.log(reg.exec(str));
console.log(str.match(reg)); //都能捕获到
var reg = /abc(\d+)/g;
var str = "abc123abc456abc789";
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(str.match(reg)); //只能捕获大正则匹配内容
replace(oldStr,newStr); 在不使用正则情况下,每使用一次只能替换一个字符
var str = "abcd2015abcd2016";
str.replace("abcd","abcde").replace("abcd","abcde");
console.log(str);
str.replace(/abcd/g,"abcde");
replace第一项查看正则原理 像exec一样,把所有匹配内容都捕获到,统一替换成目标字符串
str.replace(/abcd/g),function(){
console.log("replace");
return "abcde";
}
当第二个参数换为函数时,该匿名函数执行次数取决于正则捕获次数
函数参数:
1).arguments[0]:exec捕获数组的第一项;
2).arguments[1]:exex捕获数组的Index;
3).arguments[1]:exex捕获数组的input内容,即原始字符串;
4).若/(ab)(cd)/分组后,则不仅捕获大正则内容,还能捕获小分组内容.
每一次执行匿名函数时,里面传递的参数值arguments和通过exec捕获到的结果是类似的(即使正则有分组,也可以通过arguments获取到分组内容)
var str = "2016"
var arr = ["零","壹","贰","叁","肆","伍","陆","柒","捌","玖"];
str = str.replace(/\d/g,function(){
return arr[arguments[0]];
})
//获取字符串中出现次数最多的字符
var str = "fgjkdsafsadfnakfbdsafgdafdsfffjdj";
//获取给一个字符出现的次数
var obj = {};
str.replace(/[a-z]/gi,function(){
var val = arguments[0];
if(obj[val] >= 1){
obj[val] += 1;
}else{
obj[val] = 1;
}
});
console.log(obj);
var max = 0;
for(var key in obj){
obj[key] > max ? max = obj[key] : null;
}
var arr = [];
for(var key in obj){
obj[key] === max ? arr.push(obj[key]) : null;
}
console.log(arr);
//模板引擎实现原理
var str = "My name is {0},my age is {1},and I come from {2}.My favorite is {3}.";
var arr = ["Amy",12,America,"cooking"];
str.replace(/(\d+)/g,function(){
return arr[arguments[1]];
//因为捕获的为小正则,所以为arguments[1]项
});
console.log(str);
//截取链接中的信息
var str = 'https://mail.qq.com/cgi-bin/frame_html?sid=Xjf8ScPeUWP0Imcw&r=1ab0aea21033bf4164c1187edac80cfa';
var reg = /([^?=&]+)=([^?=&]+)/g;
var obj = {};
var res = reg.exec(str);
while(res){
obj[res[1]] = res[2];
res = reg.exec(str);
}
console.log(obj)
var str = "2016-7-26 16:30:3";
//2016年07月26日 16时30分03秒
var arr = [];
var reg0 = /^(\d{4})[-/](\d{1,2})[-/](\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2})$/g;
str.replace(reg0,function(){
arr = [].slice.call(arguments);
arr = arr.slice(1,7);
})
var resStr = "{0}年{1}月{2}日 {3}时{4}分{5}秒";
//var arr = ["2016","7","26","16","30","3"];
var reg = /{(\d+)}/g;
resStr = resStr.replace(reg,function(){
var num = arguments[1];
var val = arr[num];
if(val<10){
val = "0"+val;
}
return val;
})
console.log(resStr);