定义:它就是一个规则,用来处理字符串的一个规则html
用来处理字符串的一个规则 (正则只能处理字符串)正则表达式
regexp.test(string)
,匹配。regexp.exec(string)
, 捕获。正则的处理统称为两个方面:正则的匹配,正则的捕获
功能:检索、替换、校验数组
JS可视化工具浏览器
建立正则对象
字面量方式:函数
var reg = /\d/;
实例建立方式:工具
var reg = new RegExp('\d'); // 参数是正则字符串
两种建立方式的区别:url
//
之间包起来的全部内容都是元字符var reg = new RegExp('^\\d+' + name + '\\d+$', 'g');
每一个表达式都是由元字符和修饰符组成的spa
元字符:在//
之间具备意义的一些字符code
特殊意义的元字符
\
转义字符^
以某一个元字符开始$
以某一个元字符结尾\n
匹配一个换行符.
除了\n
之外的任意字符()
分组, 一个大的正则划分为具体的小正则.x|y|z
x,y,z其中的一个[xyz]
x,或者y,或者z,其中的一个[^xyz]
非,除了x,y,z中的任何一个字符串[a-z]
a-z中的任何一个字符[^a-z]
除了a-z任意一个字符\d
包含0-9之间的数字\D
除了0-9之间的数字之外的任何字符\b
匹配一个边界符\w
是[0-9a-zA-Z_]
,数字,字母,下划线的任意一个字符\s
匹配一个空白字符: 空格, 制表符,换页符 ...regexp
var reg = /\d/; // 包含0-9之间的数字 var reg2 = /^\d$/; // 只能是一个0-9之间的数字
表明出现次数的量词元字符
*
零到屡次(不出现,1次,100次)+
一到屡次(至少须要一次)?
零次或者一次(可能出现;可能不出现,可是出现只出现一次){n}
n次{n, }
n到屡次{n, m}
n到m次
注意点:
[]
中出现的全部字符都是表明自己意思的字符(没有特殊含义)[]
中不识别两位数x|y
默认的优先级 例如:/^18|19$/
变成 /^(18|19)$/
只能是18或19.^
,$
的效果// 有效数字正则 , 整数,负数,0,小数 // 12, 12.1, -12, +12, 0.2, // 不是有效数字状况:09 ,00ffxx, 0011 // 1. "."能够出现也能够不出现,可是一旦出现,后面必须跟着一位或者多位数字 // 2. 最开始能够有+/-,也能够没有 // 3. 整数部分,一位数能够是0-9之间的一个,多位数不能以0开头。 var reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/;
匹配年龄
// 匹配年龄 , 年龄介于18-65之间 var reg = /^(1[8-9])([2-5]\d)(6[0-5])$/; // 18-19 20-59 60-65 var reg = /^(1[8-9]|[2-5]\d|6[0-5])$/;
不能直接使用18-65之间,就划分10之内的数字.
错误写法:
var reg = /^[18-65]$/;
[]
中不识别两位数
var reg = /^[12]$/; // 1或2中的其中一个 var reg = /^[12-68]$/; // (1, 2-6其中的一个,8,)其中的一个 // 数字,字母,下划线,中杆 var reg = /^[\w-]$/;
验证邮箱
简版验证:
// `@`分割,左边为:数字,字母,下划线,.,- var reg = /^[\w.-]+@[0-9a-zA-Z]+(\.[a-zA-Z]{2,4}){1,2}$/;
正则表达式:从现实的抽象成规律,一部分,一部分解决。
身份证号码验证
简版身份证验证:
var reg = /^\d{17}(\d|X)$/; var reg = /^(\d){2}(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; // 增长分组
非空验证
var reg = !/^\s*$/;
去首尾空格
var reg = /^ +| +$/g;
去除html注释
var reg = /<\!--[\s\S]*?-->/g;
exec()
捕获个格式:
是一个数组,数组中的第一项是正则捕获的内容,第二项是捕获在字符串的索引位置,第三项是原始字符串
var reg = /\d+/; console.log(reg.exec('sf11')); // [ '11', index: 2, input: 'sf11' ]
exec分为两个阶段:
正则捕获特色:
懒惰性:每一次执行
exec
只捕获第一个匹配的内容,在不进行任何处理的状况下,再执行屡次捕获,捕获的仍是第一次匹配到的内容
lastIndex
是正则每次捕获在字符串中开始查找的位置,默认值是:0
解决正则懒惰性,在正则末尾增长修饰符"g"
i
:igoreCase(i), 忽略大小写匹配m
: multiline(m), 多行匹配g
: global(g),全局匹配
加全局修饰符g
,每次正则捕获结束后,会把lastIndex
的值变为最新的值,下次捕获,从最近的值开始查找.
// 全局修饰符 var reg = /\d+/g; var str = 'sf11aaa111'; var res = reg.exec(str); var arr = []; while(res) { arr.push(res[0]); res = reg.exec(str); }
贪婪性: 正则的每次捕获都是按照匹配最长的结果捕获的。
var reg = /\d+/g; var str = 'sf2017aaa2018'; var res = reg.exec(str);
例如: 2符合正则 2017也符合,默认捕获的是2017
解决正则的贪婪性:在量词元字符后边添加
?
// 只须要匹配2,而不须要匹配2017 var reg = /\d+?/g; var str = 'sf2017aaa2018'; var res = reg.exec(str); console.log(res);
?
在正则中的做用
/\d?/
出现0或1次数字, 数字可能出现也可能不出现./\d+?/g
出现一个数字.match()
把全部和正则匹配的字符都获取到.
var reg = /\d+/g; var str = 'sf2017aaa2018'; var arr = str.match(reg); console.log(arr); // ["2017", "2018"]
match()
和exec()
区别:
正则分组的做用:
分组引用
// 分组引用 var reg = /^(\w)\1(\w)\2$/; // `\2`表示和第二个分组出现同样的东西 , `\1`表示和第一个分组出现同样的东西. console.log(reg.test('zzff')); // true console.log(reg.test('z1f_')); // false
分组捕获
正则在捕获的时候,不只仅把大正则匹配的内容捕获到,并且还能够把小分组匹配的内容捕获到.
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/; var str = "350426199403118019"; console.log(reg.exec(str)); // arr = ["350426199403118019", "35", "0426", "1994", "03", "11", "80", "1", "9", index: 0, input: "350426199403118019"] // arr[0] -> 大正则匹配的内容 // arr[1] -> 第一个分组捕获的内容 // arr[2] -> 第二个分组捕获的内容 // arr[3] -> 第三个分组捕获的内容 // ... // 这种现象就是分组捕获
(?:)
在分组中 ?:
只匹配,不捕获.
var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/; var str = "350426199403118019"; console.log(reg.exec(str)); // arr = ["350426199403118019", "35", "0426", "1994", "03", "11", "1", index: 0, input: "350426199403118019"]
把原有的字符替换成新的字符
每当执行一次replace只能替换一个字符
replace
的一个参数是正则:
把全部正则匹配的内容捕获到,而后捕获的内容替换成须要替换的新内容。
第二个参数能够是:
// 参数和return var str = 'xixi2017xixi2018'; str = str.replace(/\d+/g, function() { // console.log(arguments); // ["2017", 4, "xixi2017xixi2018", callee: function, Symbol(Symbol.iterator): function] // ["2018", 12, "xixi2017xixi2018", callee: function, Symbol(Symbol.iterator): function] return 222222; // 返回的值,把每次大正则匹配捕获的内容都替换该值 }); console.log(str); // xixi222222xixi222222
替换字符串中的数字为中文数字
var str = '20170606'; // -> 贰零壹柒零陆零陆 var arr = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; var reg = /\d/g; str = str.replace(reg, function($1) { console.log($1); return arr[$1]; }); console.log(str);
获取一个字符串中出现次数最多的字符
var str = 'abaaaasdffasd'; var reg = /\w+?/gi; var obj = {}; str.replace(reg, function($0) { if (obj[$0] >= 1) { obj[$0] += 1; } else { obj[$0] = 1; } }); console.log(obj); // 获取最大的,出现字符最多的。 // 在对象中获取出现最屡次数,把出现最多字符拿出。 // 在一个对象获取最大值: 假设法 // 在数组中获取最大值:1. 排序。 2. 假设法, 3. Math.max(); // 获取最多出现的次数 var maxNum = 0; for (var i in obj) { if (obj[i] > maxNum) { maxNum = obj[i]; } } // 获取全部符合出现maxNum次数的都获取到 var resArr = []; for (var key in obj) { if (obj[key] == maxNum) { resArr.push(key); } } console.log(maxNum, resArr.toString());
url 处理参数
var url = 'http://www.weibo.com/u/5688069917?pids=Pl_Official_MyProfileFeed__21&profile_ftype=1&is_all=1#_0'; var reg = /([^?=&]+)=([^?=&]+)/g; var res = reg.exec(url); var obj = {}; while(res) { obj[res[1]] = res[2]; res = reg.exec(url); } console.log(obj); // Object {pids: "Pl_Official_MyProfileFeed__21", profile_ftype: "1", is_all: "1#_0"}
var url = 'http://www.weibo.com/u/5688069917?pids=Pl_Official_MyProfileFeed__21&profile_ftype=1&is_all=1#_0'; var reg = /([^?=&]+)=([^?=&]+)/g; var res = reg.exec(url); var obj = {}; url.replace(reg, function($0, $1, $2) { obj[$1] = $2; }); console.log(obj); // Object {pids: "Pl_Official_MyProfileFeed__21", profile_ftype: "1", is_all: "1#_0"}
时间字符串格式化
// "2017-6-7 23:43:12" --> "2017年06月07日 23时:43分12秒" var str = '2017-6-7 23:43:12'; // 方法一: 字符串变数组, 经过空格,拆成两项 // ['2017-6-7', '23:43:12'] var arr1 = str.split(' '); var arrL = arr1[0].split('-'); // ["2017", "6", "7"] var arrR = arr1[1].split(':'); // ["23", "43", "12"] // 方法二: 时间格式字符串,变成时间格式对象 经过new Date(); var d = new Date(str.replace('-', '/').replace('-', '/')); // 而后经过 时间对象的操做方式 来操做 // ie 浏览器中,不识别 '-' , 须要替换成 '/' // 方法三: 正则方式, 模板匹配的方式 . 设定好目标格式,把数组中固定的项替换成指定的区域内. var str = '2017-6-7 23:43:12', resStr = '{0}年{1}月{2}日 {3}时:{4}分{5}秒'; // var reg1 = /\d+/g; // var arrDate = str.match(reg1); var reg1 = /^(\d{4})[-\/](\d{1,2})[-\/](\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2})$/g; var arrDate = []; str.replace(reg1, function() { // arrDate = [].slice.call(arguments); arrDate = Array.from(arguments); arrDate = arrDate.slice(1, 7); }); // console.log(arrDate); // var arrDate = ['2017', '6', '7', '23', '43', '12']; var reg = /{(\d)}/g; resStr = resStr.replace(reg, function($0, $1) { var num = arrDate[$1]; return num < 10 ? '0' + num : num; }); console.log(resStr); // 2017年06月07日 23时:43分12秒
分组前后出现的判断:从左向右,谁先出现就是靠前分组
方法1:
var str = '9335673817'; // 9,335,673,817 var reg = /^(\d{1,3})((?:\d{3})+)$/g; var t = str.replace(reg, function() { var result1 = arguments[1]; var reslut2 = arguments[2]; return result1 + ',' + reslut2.replace(/\d{3}(?!$)/g, function() { // 负向欲查 return arguments[0] + ','; }); });
方法2:
// 倒着数 // 9,335,673,817 // 10 - 7 - 1 // 若是字符串的长度 - 索引自己位置 - 1 模 3 == 0 ,则在这个字符串的后边加一个',' // 在数值的前方加,第一个字符串有须要再次处理。 // 在数值的后方加,就能够。 var str = '9335673817'; // 9,335,673,817 var reg = /\d(?!$)/g; // (?!$) 不去捕获最后一位 var str = str.replace(reg, function(r, i){ if ((str.length - i - 1) % 3 == 0) { return r + ','; } else { return r; } }); console.log(str);
方法3:
// 倒序处理 str = str.split('').reverse().join(''); str = str.replace(/(\d{3}(?!$))/g, '$1,'); str = str.split('').reverse().join('');
re
从文本头部到尾部开始解析。文本尾部方向叫作“前”,也就是往前走,另外一方向就是后。re
匹配规则的时候,先向前看看,是否符合断言规则。后瞻/后顾的规则相反(JS不支持后顾)/^$/
表示严格匹配,以什么开头,以什么结尾,只能在这里边
问号?
总结:
// 在正则中,把 `?`的用法和`()`的用法掌握好 // 正则中的断言 /* (?=exp) (自己不占宽度,确定的,向前看) (?!exp) (?<=exp) (?<!exp) (?:) 只匹配,不捕获 (+?) (*?) ({}?) 非贪婪性 []? ()? \d? 0次或1次 */ // 【量词】 `?`在正则中比较低调,做为量词的概率比较少。 var str = '-3.1415'; var reg = /^(\+|-)?\d+(\.\d+)?$/; // /^$/ 表示严格匹配 var reg = /^[+-]?\d+(\.\d+)?$/; // 【匹配不捕获】 (?:) 前提:问号要放在分组前面,而且后边紧跟冒号。 var reg = /^(?:\+|-)?\d+(?:\.(\d+))?$/; // /^$/ 表示严格匹配 // 【非贪婪性】 把问号放在量词后边: +? *? {}? (+?) (*?) ({}?) // 正则的特色: 懒惰,贪婪。 var reg = /\d+/; var str = 'abc2342xyz236asdf456456'; console.log(str.match(reg)); // str.replace(reg, function() { // console.log(arguments); // }); var reg = /(\d+)/; reg.test(str); // 匹配的存储在构造函数上RegExp.$1; 构造函数上有九个来存储匹配到值 console.log(RegExp.$1);
欲查
特色:
欲查修饰左边,若是前面没有修饰空表达式,空正则.
(?!exp) Zero-width positive lookahead
(自己不占宽度,确定的,向前看)
正则中的断言Assert
前提, 前提条件
var str = '13456789'; var reg = /(\d)(?=(?:\d{3})+$)/g; // $ 匹配到结尾 str = str.replace(reg, function() { // console.log(arguments); return arguments[0] + ','; }).replace(reg, '$1,'); console.log(str);