- 正则两个斜杠之间包起来的都是“元字符”,斜杠后面出现的都是“修饰符”
let reg = /^\d+$/g;
常用的修饰符
- i: ignore-case 忽略大写小匹配
- m: multi-line 多行匹配
- g: global 全局匹配
常用的元字符
特殊元字符
- \d 0~9之间的一个数字
- \D 非0~9之间的任意字符
- \w “数字、字母、下划线”中的任意一个 =>/[0-9a-zA-Z_]/等价于\w
- \s 匹配任意一个空白字符(包括\t制表符[TAB键四个空格])
- \b 匹配边界符 ‘zhu’(z左边和u右边就是边界) ‘zhu-feng’(z左边、u右边、f左边、g右边是边界)
- \n 匹配一个换行符
\ 转义字符(把一个普通字符转义为特殊的字符,例如:\d,把有特殊含义的转换为普通意思,例如:. 此处的点就不是任意字符,而是一个小数点
. 不仅仅是小数点,代表除了\n以外的任意字符
^ 以某个元字符开头
$ 以某个元字符结尾
x|y x或者y中的任意一个(a|z…)
[xyz] x或者y或者z中的任意一个
[^xyz] 除了x\y\z以外的任意字符
[a-z] 获取a-z中的任意一个字符([0-9] 等价于\d …)
[^a-z] 除了a-z的任意字符
() 正则分组
(?:) 当前分组只匹配不捕获
(?=) 正向预查
(?!) 负向预查
量词元字符:让其左边的元字符出现多少次
*出现零到多次? 出现零到一次
出现一到多次
{n} 出现N次
{n,} 出现N到多次
{n,m} 出现N到M次
普通元字符
- 只要在正则中出现的元字符(在基于字面方式创建),除了特殊和有量词意义的以外,其余的是普通元字符
正则捕获的懒惰性
1.
默认情况下lastlndex的值不会被修改,每一次都是从字符串开始位置查找,所以找到的永远只是第一个
2.
案例
let str = "z2019yangfan2020qihang2021"; let reg = /\d+/;/**reg. last Index:当前正则下一次匹配的起始索引位置*懒惰性捕获的原因:默认情况下lastlndex的值不会被修改,每一次都是从字符串开始位置查找,所以找到的永远只是第一个| :*/console.log(reg.lastlndex); //=>0下面匹配捕获是从STR索引零的位置开始找 console.log(reg.exec(str));console.log(reg.lastlndex); //=>0第一次匹配捕获完成,lastlndex没有改变,所以下 一次exec依然是从字符串最开始找,找到的永远是第一个匹配到的
3.
解决方案
// 方案一,自己重写exec方法(function () {function execAll(str = '') {if (!this.global) return this.exec(str);let bigAry = [],smallAry = [],res = this.exec(str);while (res) {let [big, small] = res;bigAry.push(big);if (typeof small !== "undefined") {smallAry.push(small);}res = this.exec(str);}return [].concat(bigAry, smallAry);}RegExp.prototype.execAll = execAll;})();console.log(strReg.execAll(str));let str1 = '{0}year{1}month{2}day';let reg1 = /\{(\d+)\}/g;console.log(reg1.execAll(str1));// 方案二 字符串中提供的方法// console.log(str.match(strReg));
1.
通过\数字让其代表和对应分组出现一模一样的内容
2.
案例
let str2 = 'book';let reg2 = /^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/;console.log(reg2.test(str2));
1.
默认情况下,正则捕获的时候,是按照当前正则所匹配的最长结果来捕获的
let str = '2019@2020';let reg = /\d+/;str.match(reg); // 2019
2.
取消正则捕获的贪婪性
let str = '2019@2020';let reg = /\d+?/; // <-----str.match(reg); // 2
1. 问号左边是非量词元字符:本身代表量词元字符,出现零到一次2. 问号左边是量词元字符:取消捕获时候的贪婪性3. (?:) 只匹配不捕获4. (?=) 正向预查5. (?!) 负向预查
1.
test
let str = "{0}年{1}月{2}日";let reg = /\{(\d+)\}/g;console.log(reg.test(str)); //=>trueconsole.log(RegExp.S1); //=>0console.log(reg.test(str)); //=>trueconsole.log(RegExp.$1); //=>1console.log(reg.test(str)); //=>trueconsole.log(RegExp.S1); //=>2console.logCreg.test(str)); //=>falseconsole.log(RegExp. $1) ; //=>"2”存储的是上次捕获的结果//=>RegExp.$1〜RegExp.$9:获取当前本次正则匹配后,第一个到第九个分组的信息
2.
replace 字符串替换
1.
示例
let str3 = 'korea@korea';let replace = str3.replace(/korea/g, '韩国');console.log(replace);
2.
时间字符串处理
let time = '2020-02-15';let timeReg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;let result = time.replace(timeReg, '$1年$2月$3日');console.log(result);
3.
原理
- 首 先 拿 REG和 TIME进 疔 匹 配 捕 获 , 能 匹 配 到 几 次 就 会 把 传 递 的 函 数 执
行几次(而且是匹配一次就执行一次)
- 不 仅 把 方 法 执 行 , 而 且 REPLACE还 给 方 法 传 递 了 实 参 信 息 ( 和 exec
捕获的内容一致的信息:大正则匹配的内容,小分组匹配的信息….)
在函数中我们返回的是啥,就把当前大正则匹配的内容替换成啥
time = time. replace( reg, ( big, $l, $2, S3)=>{//=>这里的$1~$3是我们自己设置的变量console. log(big, $1 , $2 , $3);});time = time. replace( reg, . arg)=>{let [ , $l, $2, $3 ] = arg;$2.length<2?$2="0" + $2 : null;$3.length<2?$3="0" + $3 : null;return `${$1}年${2}月${3}日`;});
