• 正则的test和exec方法与字符串的search,replace,match,split方法的使用


    一、先介绍一下RegExp对象的五大属性

    • 修饰符属性

      • global-------------------------全局搜索,简写g
      • ignorecase---------------------忽略字母大小写,简写i
      • multiline----------------------多行匹配,简写m
    • 非修饰符属性

      • lastIndex----------------------一个整数,标示开始下一次匹配的字符位置
      • sourse-------------------------正则表达式的原文本
    //例子一
    
    console.log(/\d{4}/.global)//false
    console.log(/\d{4}/g.global)//true
    
    console.log(/\d{4}/.ignoreCase)//false
    console.log(/\d{4}/i.ignoreCase)//true
    
    var reg = /\d{4}/g
    var str='2018ceshi2019'
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//true 4
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//true 13
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//false 0
    
    console.log(/\d{4}/.multiline)//false
    console.log(/\d{4}/m.multiline)//true
    
    console.log(/\d{4}/.source)//\d{4}
    

    上面RegExp对象的五大属性的修饰符属性在平时都能用到,不常用的是multiline,我们下面看看multiline属性的使用场景

    • 如果目标字符串中不含有换行符\n,即只有一行,那么/m修饰符没有任何意义。
    • 如果正则表达式中不含有^或$匹配字符串的开头或结尾,那么/m修饰符没有任何意义。
    var mutiline = /^abc/m;
    var singleline = /^abc/;
    var target = "ef\r\nabcd";
    console.log(mutiline.test(target));//true
    console.log(singleline.test(target));//false
    
    

    二、RegExp对象定义了两个用于模式匹配的方法,它们是exec()和test()

    1、test()

    • 如果不使用循环,全局匹配和非全局匹配结果是一样的
    • 用法:regexp.test(string)
    • 作用:对一个指定的字符串执行一个正则表达式匹配
    • 返回值:true或false
    //例子二
    
    var reg = /\d{4}/g
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//true 4
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//true 13
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//false 0
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//true 4
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//true 13
    console.log(reg.test('2018ceshi2019'),reg.lastIndex)//false 0
    

    2、exec()

    • exec()和match()方法很类似
    • 如果不使用循环,全局匹配和非全局匹配结果是一样的
    • 用法:regexp.exec(string)
    • 作用:对一个指定的字符串执行一个正则表达式匹配
    • 返回值:数组或null,数组分为两种情况,有分组(括号里匹配)和无分组
      • 若无分组则数组里的内容包含三项,分别是
        • 匹配的内容
        • 匹配内容的起始索引
        • 原字符串
      • 若有分组则数组里的内容包含多项,分别是
        • 第一项是匹配的内容
        • 第二项开始是分组(括号里匹配)的内容,有几个分组就有几项
        • 倒数第二项是匹配内容的起始索引
        • 倒数第一项是原字符串
    //例子三
    var str = "2018ceshi2019"
    
    //使用非全局匹配
    console.log(/\d\w/.exec(str));//["20", index: 0, input: "2018ceshi2019"]
    console.log(/([a-z])(\w)/.exec(str));//["ce", "c", "e", index: 4, input: "2018ceshi2019"]
    
    //使用全局匹配
    var regg=/\d\w/g
    console.log(regg.exec(str));//["20", index: 0, input: "2018ceshi2019"]
    console.log(regg.exec(str));//["18", index: 2, input: "2018ceshi2019"]
    console.log(regg.exec(str));//["20", index: 9, input: "2018ceshi2019"]
    console.log(regg.exec(str));//["19", index: 11, input: "2018ceshi2019"]
    console.log(regg.exec(str));//null
    console.log(regg.exec(str));//["20", index: 0, input: "2018ceshi2019"]
    
    var regg2=/([a-z])(\w)/g
    console.log(regg2.exec(str));//["ce", "c", "e", index: 4, input: "2018ceshi2019"]
    
    从上面的例子可以发现正则的exec()和test()方法如果不使用循环,全局匹配和非全局匹配结果是一样的

    exec适合用于循环匹配,虽然全局匹配和非全局的返回值一样,但使用exec循环时,必须要加修饰符g

    //例子四
    var str='abc,bbc,cbc,dbc';
    var reg=/(\w)bc/g;
    //循环匹配时,要先将正则表达式定义好,不然每次都是一个新的正则对象,影响lastIndex的变化
    //一定要加修饰符g,lastIndex是匹配项后面的下标,是下一次匹配的开始下标
    //当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0
    
    //exec()方法使用循环
    var resultArr=[];
    while(result=reg.exec(str)){ 
    console.log("lastIndex: "+reg.lastIndex);
    //lastIndex: 3
    //lastIndex: 7
    //lastIndex: 11
    //lastIndex: 15
    resultArr.push(result);
    }
    console.log(JSON.stringify(resultArr));//[["abc","a"],["bbc","b"],["cbc","c"],["dbc","d"]]
    
    //test()方法使用循环
    resultArr=[]
    while(result=reg.test(str)){ 
    console.log("lastIndex: "+reg.lastIndex);
    //lastIndex: 3
    //lastIndex: 7
    //lastIndex: 11
    //lastIndex: 15
    resultArr.push(result);
    }
    console.log(JSON.stringify(resultArr));//[true,true,true,true]
    

    三、String对象支持四种利用正则表达式的方法,分别为search(),replace(),match(),split()

    1、search()

    • 是否使用全局匹配,返回的结果都是一样的
    • 用法:string.search(regexp)
    • 作用:返回第一个与之相配的字符串开始的位置
    • 返回值:如果能查找到返回第一个匹配的字符的位置,如果没有匹配到,但是-1
    //例子五
    var str = "jfkdasjf"
    var reg=/a/g
    console.log(str.search(reg));//4
    console.log(str.search(/z/));//-1
    
    

    2、replace()

    • 用法1:string.replace(string,str)
    • 用法2:string.replace(regexp,str)
    • 用法3:string.replace(regexp,function)
      * function的参数()
      1.匹配的字符串
      2.正则表达式分组内容,没有分组则没有该参数
      3.匹配项在字符串中的 index
      4.原字符串
      无分组时(匹配的字符串,匹配项在字符串中的 index,原字符串)
      有分组时(匹配的字符串,正则表达式分组内容1,正则表达式分组内容2,...,匹配项在字符串中的 index,原字符串)
    • 作用:在string中找到regexp匹配的字符串,替换成str
    • 返回值:没有匹配到就返回原字符串,匹配到了就返回原字符串被替换后的字符串
    //例子六
    var str = "jfkdasjf"
    var reg = /a/g;
    console.log(str.replace(reg,"被替换了"))
    
    

    3、match()

    • 用法:string.match(regexp)
    • 作用:在string中找到regexp匹配的字符串
    • 返回值:数组或null
      • 如果匹配正则表达式,则返回一个数组;
        • 如果使用的非全局匹配,返回的结果是个数组,数组的成员是和正则的exec()方法类似
        • 如果是使用的全局匹配,返回的结果是个数组,数组的成员是,匹配到的字符串
      • 如果不匹配则返回null
    //例子七
    var str = "1a2b3c";
    
    //1使用的是非全局匹配,匹配到的是结果是数组,数组成员是[匹配到的字符,匹配到的字符的index,被匹配的字符串]
    var reg = /[\d.]/;
    console.log(str.match(reg)); //["1",groups:undefined,index:0,input:"1a2b3c"]
    console.log(JSON.stringify(str.match(reg))); //'["1"]'
    
    //2使用的是全局匹配,匹配到的结果是数组,数组的成员是[匹配到的字符串,...]
    var reg2 = /\d./g;
    console.log(str.match(reg2)); //["1a","2b","3c"]
    console.log(JSON.stringify(str.match(reg2))); //'["1a","2b","3c"]'
    
    
    //3如果使用的是全局匹配,且匹配到的结果只有一个,返回的也是和上面的2一样的
    console.log('1asdf'.match(reg2)); //["1a"]
    console.log(JSON.stringify('ab2c'..match(reg2))); //'["1a"]'
    

    4、split()

    • 用法:string.split(regexp)
    • 作用:在string中找到regexp匹配的字符串,将字符串分割成数组
    • 返回值:数组
    //例子八
    var str = "my@name#is&zhou&zhou"
    //能匹配到
    console.log(str.split(/@|#|&/g))//["my", "name", "is", "zhou", "zhou"]
    
    //不能匹配到
    console.log(str.split(/~/g))//["my@name#is&zhou&zhou"]
    

    四、通过上面的例子,我们发现正则的exec()和match()方法很类似,我们下面列举下这两种方法的区别

    1. 返回的结果
      • 共同点

        • 返回值是数组或null
        • 如果匹配正则表达式,则返回一个数组;
        • 如果不匹配则返回null
      • 不同点(前提是匹配了正则表达式,有返回值)

        • exec()方法
          • 返回的数组分为两种情况,有分组(括号里匹配)和无分组
            • 若无分组则数组里的内容包含三项,分别是
              匹配的内容
              匹配内容的起始索引
              原字符串
            • 若有分组则数组里的内容包含多项,分别是
              第一项是匹配的内容
              第二项开始是分组(括号里匹配)的内容,有几个分组就有几项
              倒数第二项是匹配内容的起始索引
              倒数第一项是原字符串
        • match()方法
          • 返回的数组不管是有分组(括号里匹配)还是无分组,返回的数组里面的元素的结构是一样的
          • 全局匹配和非全局匹配的数组结构不一样
          • 全局匹配的数组结构(["匹配的内容","匹配的内容"...])
          • 非全局匹配的数组结构(与exec方法返回的数组结构一样)
    2. 使用全局匹配和非全局匹配
      exec()方法使用全局匹配(不使用循环)和非全局匹配返回的结果是一样的
      match()方法使用全局匹配和非全局匹配,如果能匹配到,返回的数组元素的结构是不一样的,区别在上一个点里面有列举
  • 相关阅读:
    JS截取文件后缀名
    百度地图API示例:使用vue添加删除覆盖物
    AttributeError: module 'tensorflow' has no attribute 'sub'
    ModuleNotFoundError: No module named 'numpy.core._multiarray_umath' ImportError: numpy.core.multiarray failed to import
    千锋很火的SpringBoot实战开发教程视频
    sublime text3 3176 注册码 License
    linux后台运行jar程序
    使用eclipse的SVN连接码云
    关于git上传文件的一个小问题
    js正则表达式,密码长度要大于6位,由数字和字母组成
  • 原文地址:https://www.cnblogs.com/HYZhou2018/p/10650523.html
Copyright © 2020-2023  润新知