Regulax Expression由普通字符(也叫原义字符例如字符a~z)以及特殊字符(称为元字符)组成的文字模式。
一:元字符语法
1.字符类
[xyz] 字符集,匹配这个集合中的任一一个字符(或元字符) ,same as x|y|z
"a1b2c3d4".replace(/[abc]/g,"X"); //X1X2X3d4
[^xyz] 不匹配这个集合中的任何一个字符 ,不是这里面的任意一个字符
"a1b2c3d4".replace(/[^abc]/g,"X"); //aXbzXcXXX
[ ]匹配空格,注意两个中括号中间有个空格
'rgb(255, 255, 255)'.replace(/rgb\(|\)|[ ]/g,''); //'255,255,255'
2.范围类
[a-z]或者[0-9]
"a1b2c3d4".replace(/[a-z]/g,"Q"); //Q1Q2Q3Q4
"2017-10-17".replace(/[0-9-]/g,"A"); // AAAAAAAAAA
3.预定义类
. 除了回车符和换行符外所有的字符(一个字符)
\d 匹配一个字数字符,/\d/ = /[0-9]/ bound
\D 匹配一个非字数字符,/\D/ = /[^0-9]/
\s 匹配一个空白字符,包括\n,\r,\f,\t,\v等 space
\S 匹配一个非空白字符,等于/[^\n\f\r\t\v]/
\w 匹配一个可以组成单词的字符 word 字母数字下划线[a-zA-Z_0-9]
\W 匹配一个不可以组成单词的字符,如[\W]匹配"$5.98"中的$,等于[^a-zA-Z0-9]。
[\b] 匹配一个退格符
\cX 这儿,X是一个控制符,/\cM/匹配Ctrl-M
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\v 匹配一个重直制表符
3-1.边界
^ 以xxx开始 在字符类中表示取反 [^0-9]
'@123@abc@'.replace(/@./g,"X"); //X23Xbc@
'@123@abc@'.replace(/^@./g,"X"); // X23@abc@ 只以@开头的任意字符才会匹配,即1
$ 以xxx结束 但是^和$放的位置不一样,^放在前面,$放在后面
'@123@abc@'.replace(/.@$/g,"X"); // @123@abX 只以@结尾的任意字符才会匹配,即1
\b 匹配一个单词的边界
"this is a girl".replace(/is/g,"0"); //th0 0 a girl
"this is a girl".replace(/\bis/g,"0"); //this 0 a girl
"this is a girl".replace(/\Bis\b/g,"0"); //th0 is a girl
\B 匹配一个单词的非边界
4.量词
?出现零次或者一次
+ 出现一次或多次
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n到m次
{n,} 至少出现n次
4-1.贪婪和非贪婪模式
'a12345678'.replace(/\d{3,6}/g,"A"); //aA78
贪婪模式:如果直接{3,6}系统会按最大的,意思会将6个数字替换成A
非贪婪模式:加?
'a12345678'.replace(/\d{3,6}?/g,"A"); //aAA78 加了?后将三个数字换成A,但是g所以AA
5.分组 ( )
想匹配字母数字三次,如果只是"a1b2c3d4".replace(/[a-z][0-9]{3}/g,"A");虽然也是字母数字匹配三次,是不行的
使用分组才行"a1b2c3d4".replace(/([a-z][0-9]){3}/g,"A"); //"Ad4"
5-1.或 |
如果只是匹配名字中的两部分:
'ByronCasper'.replace(/Byron|Casper/g,'X'); //XX
如果匹配名字中的四个单词:
'ByronsperByrCasper'.replace(/Byr(on|Ca)sper/g,'X'); //XX
5-2-1.反向引用(自己理解就是把某个分组声明成变量,变量用$n来取值,n从1开始)
比如:2015-12-25 => 12/25/2015
'2015-12-25'.replace(/(\d{4})-(\d{2})-(\d{2})/,'$2/$3/$1');
只有用反向引用才能达到这个效果
5-2-2.反向引用但忽略分组(不用某个变量,在分组内加上?:就可以)
'2015-12-25'.replace(/(?:\d{4})-(\d{2})-(\d{2})/,'$1');
如果给第一个分组引用加上?:,那个$1就是第二个分组了
6.前瞻和后顾
正则是从前往后匹配,所以字符串尾部是前,头部是后。js不支持后顾。
- 正向前瞻exp(?=assert)
- 负向前瞻exp(?!assert)
exp表示正则表达式,(?=assert)叫断言也是正则表达式。正向前瞻就是不光匹配正则还要符合断言部分,负向前瞻就是不匹配断言部分。就是说只是匹配了正则还不行,还要看看后面的字符匹配断言不。替换或者操作的只是正则部分,不会操作断言部分。
比如要一个前面是单词且后面是数字,替换掉单词
'a2*3'.replace(/\w(?=\d)/g,"X"); //X2*3
'a2*34vv'.replace(/\w(?=\d)/g,"X"); //X2*X4vv
比如要一个前面是单词且后面不是数字,替换掉单词
'a2*34vv'.replace(/\w(?!\d)/g,"X"); //aX*3XXX
7.匹配斜杆
"2017/20/10".replace(/\//g,"-");
二:JS中正则相关函数
可以使用正则的函数可以分为两大类,一类是字符串的方法,一类是正则对象的方法。个人感觉,返回是否匹配/返回匹配的值/替换匹配值,这三个方法就满足我目前所有的需求了。
1.字符串的方法
- match 可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配
这是个宝藏方法,返回一个数组。数组第0个元素是匹配到的字符串,其余的元素存放的与正则子表达式匹配的文本。而且还有两个属性input和index,input声明的是方法传进来的字符串,index 属性声明的是匹配文本的起始字符在 stringObject 中的位置。
假设目前URL是 http://www.baidu.com?p=1&&token=v
var reg = new RegExp("(^|&)token=([^&]*)(&|$)");
var result = window.location.search.substr(1).match(reg);//window.location.search返回?及后续
console.log(result);
打印结果为:
input:'p=1&&token=v',
index:4,
[
'&token=v',
'&',
'v',
''
]
- replace //又简单又常用,注意该方法不修改调用者自身,返回的值才是修改后的
var a = 'iloveyou';
var b = a.replace(/you/,'me');
alert(a); //iloveyou
alert(b); //iloveme
第二个参数可是字符串,也可以是回调。回调内传入匹配到的值,需要再return一个参数,作为替换的值
var a = 'iloveyou';
var b = a.replace(/you/,function(para){
return 'me'; //此回调可以让我们拿到匹配到的值,下面切换大小写就有相关实例
});
alert(a); //iloveyou
alert(b); //iloveme
2.正则对象的方法
- test 如果字符串中含有匹配的文本,则返回 true,否则返回 false。
var patt = /e/;
patt.test("The best things in life are free!"); //返回true
- exec
检索字符串中的正则的匹配。返回一个数组,存放匹配的结果。未匹配,则返null。
输出的结果和字符串方法match一样
var patt = /(a)(r)/;
patt.exec('learn');
输出:["ar", "a", "r", index: 2, input: "learn", groups: undefined]
三:辅助工具
- https://regexper.com/ 这个有正则解析功能
如下基础图示,
a出现1次或多次
a自身有根线表示有一次,自己又循环多次,标识1次或多次
a出现0次或多次
a自身有根线表示有一次,上面有一根绕行的表示可能0次,下面自身又循环多次。
整体表示a出现0次或多次。
a出现0次或1次
a自身有根线表示有一次,上面有一根绕行的标识可能0次。整体表示a出现0次或1次。
四:实例
这个网站可以测试正则,而且分析的非常清楚,配合着使用非常给力
1.匹配一个“ ab+数字+任意字符 ”的字符串
预定义类写法:/ab\d./
范围类写法:/ab[0-9][^\r\n]/
2.检测电话号
function CheckPhone(InputId) {
var Patter = /[0-9]/g;
var NumLength = $("#"+InputId).val();
if(Patter.test(NumLength) && ((NumLength.length == 11) || (NumLength.length == 8))){
return true;
}else {
layer.msg("电话号码格式有误");
return false;
}
}
3.把下面英文大小写取反
var str = 'JinTianTianQiHenHao 今天天气很好,18.8 摄氏度,Go Go Go !';
str.replace(/[a-zA-Z]/g,function(para){
console.log(para);
para = (para.toLowerCase() == para) ? para.toUpperCase() : para.toLowerCase();
console.log(para);
return para;
});
4.用正则给英文单词加前后空格
var str = '点头yes摇头no,要说你好喊hello!';
var str2 = str.replace(/\b[a-zA-Z]+\b/g,function(para){
return " " + para + " ";
});
alert(str2); //点头 yes 摇头 no ,要说你好喊 hello !
5.密码强度正则,至少8-16个字符,至少1个大写字母,1个小写字母和1个数字,其他可以是任意字符:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\s\S]{8,16}$/
6.数字正则
正数: /^\d+\.?\d+$/ 正数包含正整数和正小数
负数: /^-\d+\.?\d*$/ 负数包含负整数和负小数
数字正则: /^-?\d+\.?\d*$/ 数字包含正整数、正小数、负整数、负小数
7.Email正则
Email的规则:user@mail.server.name
user可以是数字账号,也可以是英文字符。mail.server.name是域名
/^([A-Za-z0-9_\-\.])+@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
8.手机号码正则
/^1[34578]\d{9}$/
9.身份证正则
/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
10.URL正则
/^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
11.将字符串转换为驼峰格式
sName.replace(/-([a-z])/g, (_, $) => $.toUpperCase());
// 输入:'font-size' 输出:fontSize
// webkit-border-image 转换后的结果为 webkitBorderImage
12.检查重复字符串
给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false
/([a-zA-Z])\1/.test(str); //输入:'rattler',返回 true
在正则表达式中,利用()进行分组,使用斜杠加数字表示引用,
\1就是引用第一个分组,\2就是引用第二个分组。
将[a-zA-Z]做为一个分组,然后引用,就可以判断是否有连续重复的字母。
13.判断是否符合 USD 格式
给定字符串 str,检查其是否符合美元书写格式
1、以 $ 开始
2、整数部分,从个位起,满 3 个数字用 , 分隔
3、如果为小数,则小数部分长度为 2
4、正确的格式如:$1,023,032.03 或者 $2.03,错误的格式如:$3,432,12.12 或者 $34,344.3
/^\$([0-9]{1,3})(\,[0-9]{3})*(\.[0-9]{2})?$/g.test(str); // 入'$20,933,209.93' 出true
/^\$(\d{1,3})(\,\d{3})*(\.\d{2})?$/g.test(str); //这个更简洁
14.给定字符串 str,检查其是否符合如下格式
1、XXX-XXX-XXXX 2、其中 X 为 Number 类型
/^([0-9]{3})\-([0-9]{3})\-([0-9]{4})$/g.test(str); //输入:'800-555-1212' 输出:true
/^(\d{3})\-(\d{3})\-(\d{4})$/g.test(str); // 跟上面一样
15.格式化时间数据,20211119->2021-11-19
time.replace(/(\d{4})(\d{2})(\d{2})?/g,function(result,$1,$2,$3){
return $1 + '-' + $2 + ($3?('-'+$3):'');
});
16.删掉除字符串和数字外所有的字符
s = s.replace(/[^a-z0-9]/g,"");
17.判断是否都是数字
/^\d+$/.test(str);
18.替换"1111222233334444"中的非1数字
"1111222233334444".replace(/[^1]/g, ''); // /[^1]/g 表示匹配非1的字符并全
五:fiddler替换
新增替换规则时,根据正则匹配,将命中的文件替换为本地的文件。如下为规则示例
正则规则 regex:.+.\/test.js*
本地路径 E:\code\blog\test.js