正则表达式
正则:它是一个规则,用来处理字符串的一个规则
处理:
  • 匹配 判断一个字符串是否符合我们制定的规则 ->test:reg.test(str);
var reg = /\d/; //包含一个0~9之间的数字
console.log(reg.test('猪')); //false
捕获 把字符串中符合我们正则规则的内容捕获到
->exec : reg.exec(str)
var reg = /\d/;
console.log(reg.exec('1')); //["1",index:0,input:"1"]
如何创建正则
  • 通过字面量方式:
var reg = /\d/;
-通过实例的方式:
var reg = new RegExp("");
两种创建方式是有区别的
在字面量方式中,我们//之间包起来的所有的内容都是元字符,有的是具有特殊的含义,不过大部分都是代表本身的含义
var name = "zhufeng";
var reg = /^\d+"+name+"\d+$/g;
console.log(reg.test("2015zhufeng2016"));//false
console.log(reg.test('2015"""nameeee"2016'));//true
因此碰到这样的需求,只能是用实例创建的方法
var reg = new RegExp("^\\d+"+ name + "\\d+$", "g");// 为什么要\\d 因为\d是字符串,需要转义
console.log(reg.test("2015zhufeng2016"));//true
两者的区别:1、字面量方式中出现的一切都是元字符,所以不能进行变量值的拼接,实例的方式则可以
2、字面量方式中直接写\d就可以,而在实例中需要转义
正则的组成
  • 元字符:
每一个正则表达式都是有元字符和修饰符组成的
1、具有特殊意义的元字符
\ : 转义字符,转义后面所代表的含义
^ : 以某一个元字符开始
$ : 以某一个元字符结尾
\n:匹配一个换行符
.:除了\n以为的任意字符
():把一个大正则划分成几个小正则
x|y:x或者y的一个
[xyz]:x、y、z中的任意一个
[^xyz]: 除了xyz中的任意一个字符
[a-z]:匹配a-z中的任意一个字符
[^a-z]:匹配除了a-z中的任意一个字符
\w:数字、字母、下划线的任意一个字符,等价于->[0-9a-zA-Z_]
reg = /^\d$/; //只能是 一个 0-9之间的数字
console.log(reg.test('9')); //true
console.log(reg.test('012')); //false 中间有3个数字
var reg = /^0.2$/; //以0开头,以2结尾,中间可以使除了\n以外的任意字符
var reg = /^(\d+)zhufeng(\d+)$/;
[]
1、在中括号中出现的所有的字符都是代表本身意思的字符(没有特殊的含义)
2、中括号中不识别两位数
var reg = /^[12]$/; //1或者2中的一个
var reg = /^[12]$/; //1 、(2-6)中的一个、 8 这三个中的一个
()
1、分组的作用:改变x|y默认的优先级
var reg = /^18|19$/;//181, 1819,189,119都行
var reg = /^(18|19)$/;
2、代表出现次数的量词元字符
*:代表零到多次
+:出现一到多次
?:出现零到一次
{n}:出现n次
{n,}:出现n到多次
{n,m}:出现n到m次
var reg = /^\d+$/;
console.log(reg.test('2018')); //true验证手机号的正则:11位数字,第一位是1
var reg = /^1\d{10}$/;
有效数字的正则
1、“ . ”可以出现也可以不出现,但是一旦出现,后面必须跟着一位或多位数字
2、最开始可以有+/-也可以没有
3、整数部分,一位数可以使0-9之间的一个,多位数不能以0开头
var reg = /^[+-]?(\d|[1-9]\d+)(\.\d+)?$/;
2、年龄介于18~65之间
->因为不可以直接[18~65],因此需要划分:
18-19 20-59 60-65
var reg = /^(1[8-9]|[2-5]\d|6[05])$/;
3、简易版验证邮箱
左边:数字、字母、下划线、.
var reg = /^[\w.][email protected][0-9a-zA-Z]+(\.[a-zA-Z]{2,4})|{1,2}$/;
正则的捕获
exec->正则的捕获
每次捕获的时候都是先进性默认的匹配,如果没有匹配成功的,捕获的结果是null;只有有匹配的内容我们才能捕获到。
捕获的内容格式
  • 捕获的内容是一个数组
    • 数组中的第一项是当前大正则的内容
    • index:捕获内容在字符串开始的索引位置
    • input:捕获的原始字符串
  • 正则捕获的特点
    • 懒惰性: 每一次执行exec只捕获第一个匹配的内容,在不进行任何处理的情况下,在执行多次捕获,捕获的还是第一个匹配的内容
    • 因为lastIndex:是正则每一次捕获在字符串中开始查找的位置,默认值是0;
    • 如何解决懒惰性? ——在正则的末尾加一个修饰符 “g”
修饰符:
global(g):全局匹配
IgnoreCase(i):忽略大小写匹配
multiline(m):多行匹配
    • 原理:加了全局修饰符g,正则每一次捕获结束后,我们的lastIndex的值都变为了最新的值,下一次捕获从最新的位置开始查找,这样就可以吧所有需要捕获的内容都获取到
  • 正则的贪婪性:正则的每一次捕获都是按照匹配最长的结果捕获的
    • 解决正则的贪婪性:在量词元字符后面添加一个?就可以
?在正则中有很多的作用:
1、放在一个普通的元字符后面代表出现0-1次 /\d?/ ->数字可能出现一次或者不出现
2、放在一个量词元字符后面是取消正则捕获时候的贪婪性
//编写程序获取正则捕获的所有内容
var reg = /\d+?/g; //出现一到多个0-9之间的数字
var str = "zhufeng2017peixun2016peixun2018";
var ary = [];
var res = reg.exec(str);
while (res){
ary.push(res[0]);
res = reg.exec(str);
}
console.log(ary);
字符串中的match方法 ->把所有和正则匹配的字符都获取到
弊端:match只能捕获到大正则匹配到的内容,而小正则捕获的内容无法获取
var reg = /\d+?/g;
var str = "zhufeng2017peixun2016peixun2018";
var ary = str.match(reg);
console.log(ary);
正则分组
1、改变优先级
2、分组引用
\1代表和第一个分组出现一模一样的内容,\2代表和第二个分组出现一模一样的内容
var reg = /^(\w)\1(\w)\2$/;
console.log(reg.test("zzff"));//true
3、分组捕获:正则在捕获的时候,不仅仅把大正则匹配的内容捕获到,而且还可以把小分组匹配的内容捕获到
并不是出现分组捕获就不能用match,如果不管用exec/match都可以一次性就捕获全的,使用两个方法中的哪一个都可以,获取的结果是一样的
var reg = /^(\d{6})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/;
console.log(reg.exec("130828199012040617"));//->["130828199012040617", "130828", "1990", "12", "04", "1", index: 0, input: "130828199012040617"]
console.log("130828199012040617".match(reg));//->["130828199012040617", "130828", "1990", "12", "04", "1", index: 0, input: "130828199012040617"]
只有需要多次捕获的,match才会出现小分组的捕获不到
var str = "zhufeng[2016]peixun[2017]yangfan[2018]";
var reg = /\[(\d+)\]/g;
console.log(str.match(reg));//->["[2016]", "[2017]"] 只有大正则捕获的内容,第一个小分组每一次捕获的内容获取不到
var str = "zhufeng[2016]peixun[2017]yangfan[2018]";
var reg = /\[(\d+)\]/g;
var ary = [], res = reg.exec(str);
while (res) {
var obj = {};
obj[0] = res[0];//->每一次大正则捕获的内容 例如:"[2016]"
obj[1] = res[1];//->每一次第一个小分组捕获的内容 例如:"2016"
ary.push(obj);
res = reg.exec(str);
}
console.log(ary);
replace方法
replace()方法用于在字符串中用一些字符串替换另一些字符,或替换一个正则表达式匹配的子串
在不使用正则的情况下,每当执行一次只能替换一个字符
语法:str.replace(/zhufeng/g,replacement) replacement可以是字符串或者函数
1、匿名函数执行多少次,取决于正则能在字符串中捕获多少次
2、每一次执行匿名函数,里面传递的参数值arguments和我们自己通过exec捕获到的结果是非常类似的
JavaScript--正则表达式
3、return:你返回的结果是啥,就相当于把当前这一次大正则捕获的内容替换成你返回的内容;不写return,默认用undefined进行替换。若不想进行替换,捕获的内容是什么就返回什么,->return arguments[0];
replace的实现原理:
  • 我们和exec捕获一样,把所有和我们正则匹配的都捕获到,然后把捕获的内容替换成我们需要替换的新内容
  • /zhufeng/g ->按照这个正则把str中所有可以匹配的都捕获到,然后统一替换成我们的”zhufengpeixun”
replace案例
JavaScript--正则表达式

2、获取一个字符串中出现次数最多的字符,并获取出现的次数
var str = "zhufengpeixunzhufengqihang";
//获取每一个字符出现的次数
var obj = {};
str.replace(/[a-z]/g,function (){
var val = arguments[0];
obj[val>=1]?obj[val]+=1:obj[val] = 1;
});
//获取最多出现的次数 ->用假设法
var maxNum = 0;
for(var key in obj){
obj[key]>maxNum?maxNum=obj[key]:null;
}
//把出现最多字符的次数获取
var ary = [];
for(var key in obj){
obj[key] === maxNum?ary.push(key):null;
}
console.log("出现最多的字符:"+ary.tostring()+'出现了'+maxNum+'次');
JavaScript--正则表达式
》》》》》》》
JavaScript--正则表达式
时间字符串格式化
将2012-04-06 12:30:32转换为2012年04月06日 12时30分32秒
//第一步:将指定格式的时间字符串中的年月日等信息存入一个数组
var str = "2012-04-06 12:30:32",
reg = /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})[-/] (\d{1,2}):(\d{1,2}):(\d{1,2})$/g,
ary = [];
str.replacr(reg,function (){
ary = ([].slice.call(arguments)).slice(1,7);
})
//第二步:设定好我们目标时间格式,把数组中对应的项替换到指定的区域内
var resStr = "{0}年{1}月{2}日 {3}时{4}分{5}秒",reg = /{(\d+)}/g;
resStr = resStr.replace(reg,function (){
var num = arguments[1],val = ary[num];
val.length === 1?"0"+ary[num]:void 0;
return val;
}
方法二
var str = "2012-04-06 12:30:32";
var reg = /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})[-/] (\d{1,2}):(\d{1,2}):(\d{1,2})$/g;
var newStr = str.replace(reg,'$1年$2月$3日$4时$5分$6秒'
检测数据类型的四种方式
1、typeof 用来检测数据类型的运算符
2、instanceof 检测某一个实例是否属于某个类
3、constructor 构造函数,作用和instanceof作用相似
4、Object.prototype.toString.call()
对于特殊的数据类型null和undefined,他们的所属类是Null和Undefined,但是浏览器把这两个类保护起来了,不允许我们访问和使用
  • typeof
使用typeof检测数据类型,首先返回的都是一个字符串,其次字符串中包含了对应的数据类型->number 、string、boolean 、null 、undefined 、function 、object
局限性:
①typeof null -> object
②不能具体的戏份是数组还是正则,还是对象中其他的值,因为使用typeof检测数据类型,对于对象数据类型中的所有的值,最后返回的结果都是字符串”object“
  • instanceof
JavaScript--正则表达式

局限性:
不能用来检测和处理字面量方式创建出来的基本数据类型的值 ——对于基本数据类型,字面量方式创建出来的结果和实例创建出来的结果是有一定的区别的,从严格意义上来讲,只有实例创建出来的结果才是标砖的对象数据类型值,也是标准的Number这个类的一个实例
![Alt text](./1524483671396.png
②只要早当前实例的原型链上,检测出来的结果都是true
JavaScript--正则表达式
  • constructor
JavaScript--正则表达式

局限性:我们可以把类的原型进行重写,在重写的过程中很有可能把之前出现的constructor覆盖了,这样检测出来的结果就不准确
  • Object.prototype.toString.call() 最准确的常用方式
①首先获取Object原型上的toString方法,让方法执行,并改变方法中this关键字的指向
JavaScript--正则表达式
Object.prototype.toString.call()的作用是返回当前方法的执行主体
②toString的理解:
JavaScript--正则表达式

用法:
JavaScript--正则表达式
console.log(({}).toString.call(new Date));
其中({})相当于Object.prototype,跟[].toString一样,都是到Array的原型中找toString方法
JavaScript--正则表达式

相关文章: