就是一个规则,用来处理字符串的一个规则(正则就是用来处理字符串的)
- API
* test
* 判断一个字符串是否符合我们制定的规则 reg.test(str); 返回布尔值
* exec
* 把字符串中符合我们正则的内容捕捉到 res=reg.exec('12345a123') 返回匹配到的内容
正则的元字符和简单应用
每个正则表达式都是由元字符和修饰符组成的
- 常用的元字符
\ 转译字符
^ 以某个元字符开始
$ 以某个元字符结尾
* 出现0次到多次
+ 出现一次到多次
? 出现0次或1次
{n} 出现N次
{n,} 出现至少N次
{n,m} 出现N次到M次
. 除了\n
() 分组把一个大正则划分成几个小正则
X|Y X或Y的一个
[XYZ] XYZ中的一个
[^XYZ] 除了XYZ
[A-Z] A-Z中的一个
[^A-Z] 除了A-Z之间的任意一个
\d 一个0--9之间的数字
\b 一个边界符 单词两边的空格 边界
\w 数字 字母 下划线 任意一个字符
\s 匹配一个空白字符 空格 换行符 换页符等
- 常用的修饰符
* g 全局匹配
* i 不区分大小写
* m 多行匹配
懒惰性和贪婪性
- 正则的捕捉
exec
捕捉的内容格式
* 捕捉的内容是一个数组
* 数组的第一项是当前正则捕获
* index 捕获内容在字符串中开始的索引位置
* input 捕捉的原始字符串
* 每一次捕捉的时候都是进行默认的匹配,如果没有匹配成功的 捕获的结果是null 只有匹配到的内容才会捕捉到
- 正则捕捉的特点
懒惰性--就是只会找一处,找到一处就不在找了
- 每一次执行exec只能捕获一个匹配的内容,在不进行处理的情况下,再执行多次捕获,捕获的还是一个匹配的内容
- lastIndex:是正则每一次捕捉在字符串中开始查找到额位置,默认值是0,每一次捕捉都是从字符串0索引开始查找
- 解决正则的懒惰性----在正则的末尾加修饰符’g‘
var reg=/\d+/g
var res=reg.exec('12345a123');
var arr=[]
while(res){
arr.push(res[0])
res=reg.exec('12345a123')
}
arr //["12345", "123"]
res //null 因为查到最后一个没有了就是null
- 注:字符串中的match方法
- 把所有和正则匹配的字符都获取到
- 虽然在当前情况下match会比exec更简便,但是match存在一些自己处理不了的问题,在分组情况下,match只能捕获大正则匹配的内容
- 而对于小正则匹配的内容是无法获取的
贪婪性--正则的每次捕获都是按照最长的结果捕获的
解决正则的贪婪性---在量词元字符后面添加一个?即可
- ? 在正则中的作用
<1>放在普通元字符后边表示出现0--1次
<2>/\d?/ 表示数字可能出现也可能不出现
<3>放在一个量词后边是取消捕捉时候的贪婪性
<4>小正则 (?:)职匹配不捕获
正则分组 、
*正则内 \1 代表复制分组的第一个小正则
- 正则分组作用
* 1. 改变优先级
* 2. 分组引用
* 3. \2代表和第2个分组一模一样,\1代表和第1个分组一模一样。。。
* var reg=/^(\w)\1(\w)\2/ console.log(reg.test('wwcc')) ---->true
分组捕获
- 正则捕获的时候不仅仅把大正则匹配的内容捕获得到 还可以吧小正则匹配的内容捕捉到
* var reg=/^(\d{2})(\d{4})/
* var str='123456'
* var arg=reg.exec(str);
* arg[0] 大正则匹配的内容
* arg[1] 小正则第一个分组匹配的内容
字符串的方法 replace、RegExp.$1得到第一分组内容
- 将原有的字符串换成新的字符,在不是用正则的情况下,每执行一次替换一处
* replace 第一项的值是一个正则,实现原理 * 首先和exec一样,把所有和我们正则匹配的 都捕获到,然后把捕获的内容替换成我们需要替换的新内容 * str=str.replace(/ba/g,function(){ console.log(arguments);//每一次arguments的值和/ba/g.exec(str)获取的值是一样的 利用argument可以拿到分组中的所有内容,为我所用 return bawuzhan; //把匹配到的都替换为return的东西 * }) * 返回一个替换后的新字符串 * 解释: * 1.匿名函数执行多少次,取决于正则在字符串中捕获多少次 * 2.每一次执行匿名函数,里面传递的参数值arguments和通过exec捕获到的结果非常相似 * (即使正则有分组,我们同样可以通过arguments获取分组捕获的内容) * 3.return 返回的结果是啥,就相当于这一次大正则 捕获的内容替换成返回的内容 * arguments[0]每一次执行匿名函数都可以把替换内容获取到 * arguments[1]每一次执行匿名函数,正则捕获到第一个小正则的内容
*RegExp.$1 获取第一个小正则分组内容
正则应用
- 将小写数字换成中文数字
var strList=['零','壹','贰','叁','肆','伍','陆','柒','捌','玖']
var num='8962738';
num=num.replace(/\d/g,function(){
if(arguments[0]) {
return strList[arguments[0]];
}
})
console.log(num)
- 获取一个字符串中出现最多次数的字符和出现的次数
var str='拉拉手哈哈啊啊啊哈阿是哦扫啊啊手啊啊';
var obj={};
str.replace(/\S/g,function(){
var val=arguments[0];
obj[val]>=1?obj[val]+=1:obj[val]=1
})
console.log(obj)
or
for(var i=0;i<str.length;i++){
var cur=str[i];
console.log(cur)
if(obj[cur]>=1){
obj[cur]++;
}else{
obj[cur]=1;
}
}
console.log(obj)
var max=0;
for(var k in obj){
if(obj[k]>max){
max=obj[k];
}
}
console.log(max);
var ary=[];
for(var key in obj){
obj[key]==max?ary.push(key):null;
}
console.log(ary);
- 把url中的参数都获取到 并且保存成一个对象
var obj={};
var reg=/([^?=&]+)=([^?=&]+)/g;
str.replace(reg, function () {
obj[arguments[1]]=arguments[2]
})
console.log(obj)
- 时间字符串格式化
String.prototype.myFormatTime=function(){
var reg=/^(\d{4})(?:-|\/|\.|:)(\d{1,2})(?:-|\/|\.|:)(\d{1,2})(?:\s+)(\d{1,2})(?:-|\/|\.|:)(\d{1,2})(?:-|\/|\.|:)(\d{1,2})$/g;
// (?:-|\/|\.|:) 表示匹配但是不捕获 - \ . : 这几个分隔符
var ary=[];
this.replace(reg,function(){
ary=([].slice.call(arguments)).slice(1,7);//获取小分组的时间
})
var format=arguments[0]||'{0}年{1}月{2}日 {3}:{4}:{5}';
return format.replace(/{(\d+)}/g,function(){
var val=ary[arguments[1]];
return val.length==1?"0"+val:val
})
}
var str ="2017.5.18 14:53:0";
console.log(str.myFormatTime('{0}年{1}月'))
console.log(str.myFormatTime('{0}/{1}/{2} {3}:{4}:{5}'));
console.log(str.myFormatTime('{0}-{1}-{2} {3}:{4}:{5}'));
console.log(str.myFormatTime());
常用的正则
//正整数
/^[0-9]*[1-9][0-9]*$/;
//负整数
/^-[0-9]*[1-9][0-9]*$/;
//正浮点数
/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/;
//负浮点数
/^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/;
//浮点数
/^(-?\d+)(\.\d+)?$/;
//email地址
/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;
//url地址
/^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$/;
或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$
//年/月/日(年-月-日、年.月.日)
/^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/;
//匹配中文字符
/[\u4e00-\u9fa5]/;
//匹配帐号是否合法(字母开头,允许5-10字节,允许字母数字下划线)
/^[a-zA-Z][a-zA-Z0-9_]{4,9}$/;
//匹配空白行的正则表达式
/\n\s*\r/;
//匹配中国邮政编码
/[1-9]\d{5}(?!\d)/;
//匹配身份证
/\d{15}|\d{18}/;
//匹配国内电话号码
/(\d{3}-|\d{4}-)?(\d{8}|\d{7})?/;
//匹配IP地址
/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/;
//匹配首尾空白字符的正则表达式
/^\s*|\s*$/;
//匹配HTML标记的正则表达式
< (\S*?)[^>]*>.*?|< .*? />;
//sql 语句
^(select|drop|delete|create|update|insert).*$
//提取信息中的网络链接
(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
//提取信息中的邮件地址
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
//提取信息中的图片链接
(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
//提取信息中的 IP 地址
(\d+)\.(\d+)\.(\d+)\.(\d+)
//取信息中的中国手机号码
(86)*0*13\d{9}
//提取信息中的中国邮政编码
[1-9]{1}(\d+){5}
//提取信息中的浮点数(即小数)
(-?\d*)\.?\d+
//提取信息中的任何数字
(-?\d*)(\.\d+)?
//电话区号
^0\d{2,3}$
//腾讯 QQ 号
^[1-9]*[1-9][0-9]*$
//帐号(字母开头,允许 5-16 字节,允许字母数字下划线)
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
//中文、英文、数字及下划线
^[\u4e00-\u9fa5_a-zA-Z0-9]+$