JS正则表达式

泄露秘密 提交于 2020-03-27 00:11:00

var matches = pattern1.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern1.lastIndex); //0

matches = pattern1.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern1.lastIndex); //0

var pattern2 = /.at/g;

var matches = pattern2.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern2.lastIndex); //3

var matches = pattern2.exec(text);
console.log(matches.index); //5
console.log(matches[0]); //bat
console.log(pattern2.lastIndex); //8
复制代码
注意:IE的JavaScript实现lastIndex属性上存在偏差,即使在非全局模式下,lastIndex属性每次也都在变化。

test()方法
正则表达式常用方法test(),它接受一个字符串参数。在模式与该参数匹配的情况下返回true,否则返回false。

用法:正则.test(字符串)

例1:判断是否是数字

复制代码
var str = '374829348791';
var re = /\D/; // \D代表非数字
if( re.test(str) ){ // 返回true,代表在字符串中找到了非数字。
alert('不全是数字');
}else{
alert('全是数字');
}
复制代码
例2:

var text ="000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;
if(pattern.test(text)){
console.log('the pattern was matched.');
}
search()方法
在字符串搜索符合正则的内容,搜索到就返回出现的位置(从0开始,如果匹配的不只是一个字母,那只会返回第一个字母的位置), 如果搜索失败就返回 -1

用法:字符串.search(正则)

例子:在字符串中找字母b,且不区分大小写

var str = 'abcdef';
var re = /B/i;
//var re = new RegExp('B','i'); 也可以这样写
alert( str.search(re) ); // 1
match方法
语法:

stringObject.match(searchvalue)
stringObject.match(regexp)
searchvalue:必需。规定要检索的字符串值。
regexp:必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。
如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组。

例如:

"186a619b28".match(/\d+/g); // ["186","619","28"]
如果上面的匹配不是全局匹配,那么得到的结果如下:
["186", index: 0, input: "186a619b28"]

replace方法
replace 本身是JavaScript字符串对象的一个方法,它允许接收两个参数:

replace([RegExp|String],[String|Function])

第1个参数可以是一个普通的字符串或是一个正则表达式.
第2个参数可以是一个普通的字符串或是一个回调函数.

如果第2个参数是回调函数,每匹配到一个结果就回调一次,每次回调都会传递以下参数:

result: 本次匹配到的结果

1,...1,...9: 正则表达式中有几个(),就会传递几个参数,1 1 9分别代表本次匹配中每个()提取的结果,最多9个

offset:记录本次匹配的开始位置

source:接受匹配的原始字符串

以下是replace和JS正则搭配使用的几个常见经典案例:

(1)实现字符串的trim函数,去除字符串两边的空格

复制代码
String.prototype.trim = function(){

//方式一:将匹配到的每一个结果都用""替换
return this.replace(/(^\s+)|(\s+$)/g,function(){
return "";
});

//方式二:和方式一的原理相同
return this.replace(/(^\s+)|(\s+$)/g,'');
};
复制代码
^s+ 表示以空格开头的连续空白字符,s+$ 表示以空格结尾的连续空白字符,加上() 就是将匹配到的结果提取出来,由于是 | 的关系,因此这个表达式最多会match到两个结果集,然后执行两次替换:

复制代码
String.prototype.trim = function(){
/**

  • @param rs:匹配结果
  • @param $1:第1个()提取结果
  • @param $2:第2个()提取结果
  • @param offset:匹配开始位置
  • @param source:原始字符串
    */
    this.replace(/(^\s+)|(\s+$)/g,function(rs,$1,$2,offset,source){
    //arguments中的每个元素对应一个参数
    console.log(arguments);
    });
    };

" abcd ".trim();
复制代码
输出结果:

[" ", " ", undefined, 0, " abcd "] //第1次匹配结果
[" ", undefined, " ", 5, " abcd "] //第2次匹配结果
(2)提取浏览器url中的参数名和参数值,生成一个key/value的对象

复制代码
function getUrlParamObj(){
var obj = {};
//获取url的参数部分
var params = window.location.search.substr(1);
//[^&=]+ 表示不含&或=的连续字符,加上()就是提取对应字符串
params.replace(/([&=]+)=([&=]*)/gi,function(rs,$1,$2){
obj[$1] = $2;
});

return obj;
}
复制代码
/([&=]+)=([&=]*)/gi 每次匹配到的都是一个完整key/value,形如 xxxx=xxx, 每当匹配到一个这样的结果时就执行回调,并传递匹配到的key和value,对应到$1和$2

(3)在字符串指定位置插入新字符串

复制代码
String.prototype.insetAt = function(str,offset){

//使用RegExp()构造函数创建正则表达式
var regx = new RegExp("(.{"+offset+"})");

return this.replace(regx,"$1"+str);
};

"abcd".insetAt('xyz',2); //在b和c之间插入xyz
//结果 "abxyzcd"
复制代码
当offset=2时,正则表达式为:(^.{2}) .表示除\n之外的任意字符,后面加{2} 就是匹配以数字或字母组成的前两个连续字符,加()就会将匹配到的结果提取出来,然后通过replace将匹配到的结果替换为新的字符串,形如:结果=结果+str

(4) 将手机号12988886666转化成129 8888 6666

复制代码
function telFormat(tel){

tel = String(tel);

//方式一
return tel.replace(/(\d{3})(\d{4})(\d{4})/,function (rs,$1,$2,$3){
return $1+" "+$2+" "+$3
});

//方式二
return tel.replace(/(\d{3})(\d{4})(\d{4})/,"$1 $2 $3");
}
复制代码
(\d{3}\d{4}\d{4}) 可以匹配完整的手机号,并分别提取前3位、4-7位和8-11位,"$1 $2 $3" 是在三个结果集中间加空格组成新的字符串,然后替换完整的手机号。

(5)replace()方法全局替换变量

简单替换字符:string.replace("a","b"); (把 a 替换成 b)
全局替换字符:string.replace(/a/g,"b");(全局把a替换成b)

但是如果是全局替换一个变量内容,如下,给一个电话号码中间加*号:

var phone = "15512345678";
var sliceNumber = phone.slice(3,phone.length - 3);
var newPhone = phone.replace(new RegExp(sliceNumber,'g'),'');
console.log(newPhone); //155
678
常用实例
匹配第一个bat或者cat,不区分大小写: /[bc]at/i 或者 new RegExp("[bc]at","i");

匹配所有以"at"结尾的3个字符组合,不区分大小写:/.at/gi;

只能输入数字:[1]*$;

只能输入n位的数字:^\d{n}$

只能输入至少n位的数字:^\d{n,}$

只能输入m~n位的数字:^\d{m,n}$

只能输入零和非零开头的数字:^(0|[1-9][0-9]*)$

只能输入有两位小数的正实数:[2]+(.[0-9]{2})?$

只能输入有1~3位小数的正实数:[3]+(.[0-9]{1,3})?$

只能输入非零的正整数:^+?[1-9][0-9]*$

只能输入长度为3的字符:^.{3}$

只能输入由26个英文字母组成的字符串:[4]+$

只能输入由数字和26个英文字母组成的字符串:[5]+$

只能输入由数字、26个英文字母或者下划线组成的字符串:^\w+$

验证用户密码:以字母开头,长度在6~18之间,只能包含字符、数字和下划线:[6]\w{5,17}$

验证是否含有%&',;=?$"等字符:[%&',;=?$\x22]+

只能输入汉字:[7]{0,}$

验证Email地址:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$

验证InternetURL:^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$

验证身份证号(15位或18位数字):^\d{15}|\d{18}$

验证IP地址:^((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$

匹配两个两个重叠出现的字符 例如,"aabbc11asd", 返回结果为aa bb 11三组match:(\w)\1

匹配成对的HTML标签:<(?[\s>]+)[>]>.</\k>

匹配1-58之间的数字:/^([1-9]|[1-5][0-8])$/

匹配 -90至90之间的整数(包括-90和90):^(-?[1-8][0-9]|-?[1-9]|-?90|0)$

匹配收尾空白字符:^\s+|\s+$

中文,全角,半角匹配:

str="中文;;a"
alert(str.match(/[\u0000-\u00ff]/g)) //半角
alert(str.match(/[\u4e00-\u9fa5]/g)) //中文
alert(str.match(/[\uff00-\uffff]/g)) //全角
找重复项最多的字符个数:

复制代码
var str = 'assssjdssskssalsssdkjsssdss';

var arr = str.split(''); //把字符串转换为数组
str = arr.sort().join(''); //首先进行排序,这样结果会把相同的字符放在一起,然后再转换为字符串
//alert(str); // aaddjjkklsssssssssssssssss

var value = '';
var index = 0;
var re = /(\w)\1+/g; //匹配字符,且重复这个字符,重复次数至少一次。
str.replace(re,function($0,$1){
//alert($0); 代表每次匹配成功的结果 : aa dd jj kk l sssssssssssssssss
//alert($1); 代表每次匹配成功的第一个子项,也就是\w: a d j k l S
  
if(index<$0.length){ //如果index保存的值小于$0的长度就进行下面的操作
index = $0.length; // 这样index一直保存的就在最大的长度
value = $1; //value保存的是出现最多的这个字符
}

});

alert('最多的字符:'+value+',重复的次数:'+index); // s 17
复制代码
判断是不是QQ号:

//^ : 放在正则的最开始位置,就代表起始的意思,注意 /[^a] / 和 /[8]/是不一样的,前者是排除的意思,后者是代表首位。
//$ : 正则的最后位置 , 就代表结束的意思

复制代码
//首先想QQ号的规则
1 首位不能是0
2 必须是 5-12位的数字

var aInput = document.getElementsByTagName('input');
var re = /^[1-9]\d{4,11}$/;
//123456abc为了防止出现这样的情况,所以必须限制最后
//首位是0-9,接着是4-11位的数字类型。

aInput[1].onclick = function(){
if( re.test(aInput[0].value) ){
alert('是QQ号');
}else{
alert('不是QQ号');
}

};
复制代码
去掉前后空格(面试题经常出现):

复制代码
var str = ' hello ';
alert( '('+trim(str)+')' );//为了看出区别所以加的括号。 (hello)
function trim(str){
var re = /^\s+|\s+$/g; // |代表或者 \s代表空格 +至少一个 前面有至少一个空格 或者后面有至少一个空格 且全局匹配
return str.replace(re,''); //把空格替换成空
}
复制代码
常用的一些表单校验:

复制代码
匹配中文:[\u4e00-\u9fa5] //中文ACALL码的范围
行首行尾空格:^\s|\s$ //首行出现任意个空格或者尾行出现任意个空格(任意表示也可以没有空格)

Email:^\w+@[a-z0-9]+(.[a-z]+){1,3}$
//起始至少为一个字符(\w字母,数字或者下划线),然后匹配@,接着为任意个字母或者数字,.代表真正的点,.后面为至少一个的字符(a-z),同时这个(比如.com)整体为一个子项作为结束,可以出现1-3次。因为有的邮箱是这样的.cn.net。(xxxx.@qq.com xxxx.@163.com xxxx.@16.cn.net )

网址:[a-zA-z]+://[^\s]* http://......
//匹配不分大小写的任意字母,接着是//,后面是非空格的任意字符

邮政编码:[1-9]\d{5} //起始数字不能为0,然后是5个数字
身份证:[1-9]\d{14}|[1-9]\d{17}|[1-9]\d{16}x
复制代码

var phoneReg = /^1[345789]\d{9}$/; 手机号正则格式
var emailReg = /^\w+((-\w+)|(.\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/; 邮箱正则格式
phoneReg .test() 判断test()里的手机号值是否为正则


  1. 0-9 ↩︎

  2. 0-9 ↩︎

  3. 0-9 ↩︎

  4. A-Za-z ↩︎

  5. A-Za-z0-9 ↩︎

  6. a-zA-Z ↩︎

  7. \u4e00-\u9fa5 ↩︎

  8. a ↩︎

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!