js进阶--正则07

正则

正则就是服务字符串的

方法
  1. 正则.test(字符串)匹配
  2. 正则.exec(字符串)捕获,有几个()捕获几次
正则的组成

正则由元字符和修饰符组成

  • 元字符
    • 量词元字符
    • [\u4E00-\u9FA5]匹配中文文字
    • * 0到多次
    • +1到多次
    • ? 0~1次
    • {n}出现n次,n为数字
    • {n,}至少出现n次
    • {n,m}出现n到m次
  • 特殊元字符
    • \转义字符,可以吧特殊的 元字符转换为普通的元字符,也可以把普通元字符转换为特殊元字符
    • .任意字符(处理换行符以外)
    • ^以什么开头,用法^2是以2开头
    • $以什么结尾,用法2$以2结尾
    • \n换行符
    • \d0到9之间的任意数字
    • \D非0到9之间的任意数字
    • \w数字、字母、下划线
    • \t制表符
    • \b单词边界
    • \s空白符
    • x|yx和y之间的任意一个
    • [a-z]a到z之间的任意一个字符
    • [a-zA-Z0-9]a到z或者A到Z或者0到9之间的任意字符
    • [^a-z]除了a到z之外的任意一个字符
    • ()分组
    • (?:)只匹配不捕获
    • (?=)正向预查
    • (?!)负向预查
  • 普通元字符
  • 修饰符
    • 就是对正则起到修饰作用
    • i不区分大小写
    • m多行匹配
    • g全局匹配

正则具有懒惰性,捕获到一个他就不走了,想让他全部捕获要加g,让他全局捕获

()
  1. 提高匹配的优先级
  2. 分组引用
  3. 分组捕获
练习

()后面加上\1是()内的再执行一遍,想再执行的话不是\2而是在\1后再加\1如()\1\1
匹配里不能出现多位数

let a="abab";
var reg=/^([a-z][a-z])\1$/;
var reg=/^([a-z]{2})\1$/

let a="abbc";
var reg=/^a([a-z])\1c$/;

//月份01-09或10-12
var reg=/^(0[1-9])|(1[0-2])$/
//简单身份证
(?:是只匹配不捕获)
var reg=/^(?:\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(?:X|\d)$/;
reg.exec("410622201012309516")
正则的创建方式
  • 字面量方式
  • 构造函数方式 new RegExp("\d+");
    • 构造函数创建的正则,\需要写两个,写一个会被定义为转义
    • 想让内容为动态的,只能用构造函数
let str="aaa"
let reg=new RegExp(`^${str}$`);
console.log(reg);//  /^aaa&/

正则的捕获

exec把正则匹配到的东西捕获到
全称RegExp.prototype.exec()

exec返回值的特点
  1. 是数组类型的,如果捕获不到就是null
  2. 数组的正常项就是捕获到的内容
  3. index是第一次捕获内容的开始位置的索引
  4. input是原来的字符串
  5. 正则身上有一个属性global,如果正则有g就是true,没有就是false
正则的懒惰性
1.正则再捕获的时候只会把第一次符合规则的内容捕获到
let str="ad123da789bfs367";
console.log(reg.lastIndex);//0
let reg=/\d{3}/;
var res=reg.exec(str);
console.log(res);//VM136:4 ["123", index: 2, input: "ad123da789bfs367", groups: undefined]
console.log(reg.lastIndex);//0
2. 正则是一个对象,身上有lastIndex属性,控制的是当前正则捕获开始位置的索引

到最后查找不到了为null,然后从0开始,重新查找
取消懒惰性的话+g,每一次捕获,改变lastIndex,也就是改变下一次捕获开始的索引,但是一次一次的查找的,有些麻烦

let str="ad123da789bfs367";
let reg=/\d{3}/g;
console.log(reg.lastIndex);//0
var res=reg.exec(str);
console.log(res);
console.log(reg.lastIndex);//5
res=reg.exec(str);
console.log(res);
console.log(reg.lastIndex);//10
res=reg.exec(str);
console.log(res);
console.log(reg.lastIndex);//16
res=reg.exec(str);
console.log(res);//null
console.log(reg.lastIndex);//0
封装一个方法,可以把当前字符串所有符合正则规则的内容全部捕获到,并且以数组方式返回
let str = "ad123da789bfs367";
let reg = /\d{3}/;
RegExp.prototype.myExec = function (str) {
    let ary=[];
    var res=this.exec(str);
    if(!this.global){
        ary.push(res[0]);
    }else{
        while(res){
            ary.push(res[0]);
            res=this.exec(str);
        }
    }
    return ary.length?ary:null;
}
var res = reg.myExec(str);
console.log(res);
match是字符串身上的方法,用来配合正则使用

如果正则不加g,那方法返回的值跟exec一样
如果正则匹配不到那返回null
正常情况下返回的是一个数组,数组里存放的是符合规则的每一个内容
其他特点(也可以称为缺陷)

  • match不能捕获到小分组()的内容,只能捕获符合整个正则的字符串
//结果跟自己封装的myExec一样
str.match(reg);
matchAll是字符串的一个方法,但是可以获取到()内的内容
let str = "ad123da789bfs367";
let reg = /\d{3}/;
let Iterator = str.matchAll(reg);
for (let item of Iterator) {
    console.log(item);
}
//封装一个字符串方法,既可以得到大正则捕获的内容,还可以得到每一次分组捕获的内容
function myMatch(reg){
    if(!reg.global){
        return reg.exec(this);
    }
    let obj={
        big:[],
        small:[]
    };
    let Iterator=this.matchAll(reg);
    for(let item of Iterator){
        obj.big.push(item[0]);
        obj.small.push(item[1]);
    }
    return obj.big?obj:null;
}
String.prototype.myMatch=myMatch;
let str = "ad123da789bfs367";
let reg = /(\d{3})/g;
str.myMatch(reg);

function myMatch(reg){
    let res=reg.exec(this);
    let obj={
        big:[],
        small:[]
    };
    if(!reg.global){
        return reg.exec(this);
    }
    while(res){
        obj.big.push(res[0]);
        obj.small.push(res[1]);
        res=reg.exec(this);
    }
    return obj.big?obj:null
}
String.prototype.myMatch=myMatch;
let str = "ad123da789bfs367";
let reg = /\d{2}(\d)/g;
str.myMatch(reg);
正则的贪婪性

当正则捕获的时候能多捕获一个就多捕获一个

let str="2019";
let reg=/\d+/g;
console.log(str.match(reg));//["2019"]

取消正则的贪婪性,在后面加?

let str="2019";
let reg=/\d+?/g;
console.log(str.match(reg));// ["2", "0", "1", "9"]
正则类上的$1-$9存储的是正则匹配到的分组内容,但每次使用正则都会覆盖前面的

replace

replace第一个值可以传正则
第二个值可以传函数,字符串
字符串为替换,函数的时候,正则匹配成功几次,函数执行几次,且每次匹配成功会把捕获到的传递给函数可以用arguments等其他方式接收
当为函数时候,函数内return 返回的什么就把匹配到的替换成什么,如果没有return就替换为undefined

let str="qfevws123qfegs456fs789";
let reg=/\d{3}/g;
let res=str.replace(reg,function(){
    //replace第一个传正则,第二个传函数的时候
    //正则捕获成功几次,当前回调函数就执行几次,每次捕获的时候都会把当前捕获的内容传递给回调函数
    console.dir(arguments);
    return "pp";
    //return 返回的什么就把匹配到的替换成什么,如果没有return就替换为undefined
})
console.log(res);//"qfevwsppqfegsppfspp"
将?后的以=为分割,放在一个对象中返回
//?传参
//第一种
let url = "http://www.baidu.com?name=erya&age=18&sex=0#index";
String.prototype.URLParams = function () {
    var newObj = {};
    let reg = /([^#*=&?]*)=([^#&?=*]*)/g
    let Iterator = this.matchAll(reg);
    console.log(Iterator)
    for (let item of Iterator) {
        newObj[item[1]] = item[2]
    }
    return newObj;
}
url.URLParams();

/第二种
let url = "https://www.baidu.com/s?wd=%E7%88%B1%E6%93%A6&rsv_spt=1&rsv_iqid=0x95896f7c00000872&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=80035161_1_dg&rsv_enter=1&rsv_dl=tb&rsv_sug3=3&rsv_sug1=1&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&inputT=1208&rsv_sug4=1306";
String.prototype.URLParams = function () {
    var newObj = {};
    let reg = /([^#*=&?]*)=([^#&?=*]*)/g;
    this.replace(reg, function (a, ...arg) {
        newObj[arg[0]] = arg[1];
    })
    return newObj;
}
url.URLParams();
分割时间
//时间2019年12月03日 12时10分03秒

/1
let time = "2019-12-3 12:12:12";
String.prototype.myTime = function (tem = "{0}年{0}月{0}日 {0}时{0}分{0}秒") {

    let reg = /(\d+)/g
    let timeAry = this.match(reg);
    let time2 = tem.match(/[^\{\d\}\s]/g);
    // console.log(time2)
    let a = ``;
    for (var i = 0; i < time2.length; i++) {
        if (timeAry[i].length < 2) {
            timeAry[i] = "0" + timeAry[i];
        }
        // timeAry[i]=timeAry[i]||"0";
        // time2[i]=time2[i]||"0";
        a += (timeAry[i] + time2[i])
    }
    return a;
}
time.myTime();


//2
let time = '2019-12-3 12:12:3';
// 想要得到这样的结果 ==>'2019年12月03日 12时10分03秒'
function formatTime(template = '{0}年{1}月{2}日 {3}时{4}分{5}秒') {
    let timeAry = this.match(/\d+/g);// 把字符串里的年月日时分秒都拿到,以数组的格式进行展示 ["2019", "12", "3", "12", "10", "3"]
    // let template = '{0}年{1}月{2}日 {3}时{4}分{5}秒';// 编写一个模板,一会用来进行替换
    template = template.replace(/\{(\d)\}/g, function (content, index) {
        // index是每一次分组捕获的内容
        // console.log(content, index)
        // console.log(timeAry[index])
        console.log(content,index)
        let time = timeAry[index] || "00"; // 如果index获取不到对应的值,那就默认赋值为 "00"
        time.length < 2 ? time = "0" + time : null;
        // 如果获取的时间不足十位就补零
        return time;
    })
    return template
    console.log(timeAry)
}
String.prototype.formatTime = formatTime;
console.log(time.formatTime())
首字母大写
//首字母大写
let str = "good good study,day day up";
let reg = /\b[a-zA-Z]/g;
var res = str.replace(reg, function () {
    return arguments[0].toUpperCase();
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值