• 10、正则表达式 (笔试题、语法规则、正则对象方法、正则实例属性、支持正则表达式的String对象的方法、贪婪匹配与非贪婪匹配)


    正则表达式

    正则表达式的笔试题:

    方法一去除头尾空格str.trim()

    方法二去除所有空格:正则表达式   str. replace (/\s*/g,"");  

    方法三去除头尾空格:正则表达式  

    1. //前后空格
    2. var str=" hello "
    3. var reg=/(^\s+)|(\s+$)/g
    4. var re=str.replace(reg,"")
    5. console.log(re)
    1. //判断自循环重复次数或者是否存在
    2. //是否存在 indexOf和match两种方法
    3. var str="helloabxh"
    4. var reg=/lo/
    5. // var re=str.indexOf("lo")
    6. var re=str.match(reg)
    7. console.log(re)
    8. //重复次数--indexOf
    9. var str="helloabc"
    10. var count=0
    11. var temp=0
    12. while(str.indexOf("lo",temp)!=-1){
    13. count++
    14. temp=str.indexOf("lo",temp)+1
    15. }
    16. console.log(count) //1
    17. //重复次数--方法二正则表达式--match
    18. var str="helloalbxh"
    19. var reg=/l/g
    20. var re=str.match(reg)
    21. console.log(re.length) //3

    正则表达式必会: test、exec

    字符串必会: match、replace、search、split

    正则表达式属于字符串的相关操作

    正则表达式RegExp(Regular Expression):匹配 特殊字符或有特殊搭配原则的字符 的最佳选择。

    eg:匹配“XYXY”格式字符串。xxyy xyzz

    小知识点:

    • 转义字符\,在反斜杠\后边放的紧挨着得字符被强制转化成文本

      eg:
          \"-----实现在双引号里再放双引号
          \r-----行结束符,即回车
          \.-----就是.的意思
          \t-----制表符,键盘得tab键
    • 多行字符串

      eg: 
          \------还可以转义回车(换行)符号,实现js语法上的多行字符串
    • 换行的转义字符

      eg: 
          \n------实现换行

    10.1 语法规则

    10.1.1 创建方法

    两种创建方式:

    1、直接量

    其本身是一个对象,表达的意义是一种规则。

    (1)在两个斜杠中间写规则。

    var  reg=/abc/;
    var  str="abcd";
    reg.test(str)  ;    //true 检查在字符串str中有没有符合reg规则得字符(看str是否包含reg)

    (2)在正则表达式得双斜杠后边还可以加字母i、g、m,表达其属性。

    //i===》ignorcase,忽略大小写
    //eg:
    var  reg=/abce/i;
    var  str="ABCEd";
    reg.test(str)  ;

    2、构造方法RegExp()

    //使用new操作符,new RegExp();
    //eg:
    var reg=new RegExp("abc");
    var str="abcd";
    reg.test(str);
    ​
    //在new RegExp("abc")函数里边也可以添加属性i、g、m
    //eg:
    var reg=new RegExp("abc","im");
    var str="abcd";

    使用new操作符,可以将已经存在的正则表达式用来给函数RegExp()传参,构造新的正则表达式。

    //reg与reg1值相同,但两个两个值相互独立,即reg!=reg1
    //eg:
    var reg=/abce/m;
    var reg1=new RegExp(reg);

    若去除new操作符,将已经存在的正则表达式用来给函数RegExp()传参,只是传递引用,不能构建新的正则表达式,极少的用法。

    //reg与reg1只是对同一个正则表达式的引用
    //eg:
    var reg=/abce/m;
    var reg1=RegExp(reg);
    reg.abc=3;
    console.log(reg1.abc);//3

    10.1.2 三个属性i,g,m

    正则表达式的属性(也称修饰符),可以在全局搜索中不区分大小写:

    i ---》(ignoreCase )执行匹配时忽略大小写 g---》(global)执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)

    使用字符串的match方法  :查找是否有匹配值
    
    1. var reg=/ab/;
    2. var str="ababababab";
    3. str.match(reg);//["ab"],只查找到第一个匹配值便返回
    4. reg=/ab/g;
    5. str.match(reg);//["ab","ab","ab","ab","ab"],全局查找,把所有匹配值均返回

    m---》(multiline)执行多行匹配

    ^: 以什么开头的          $:   表示结尾
    1. var reg=/a/g;
    2. var str="abcdea";
    3. str.match(reg);//["a","a"]
    4. reg=/^a/g;//插入符^指的是以字母a为开头
    5. str.match(reg);//["a"]
    6. str="abcde\na";
    7. str.match(reg);//["a"],还没有多行匹配属性
    8. reg=/^a/gm;
    9. str.match(reg);//["a","a"]

    #####10.1.3 方括号

    A--a  也是一个范围

    方括号用于查找某个范围内的字符:

    一个中括号代表一位,中括号里边的内容代表的是这一位可以取值的范围

    1. //eg1:
    2. var  reg=/[1234567890][1234567890][1234567890]/g;
    3. var  str="12309u98723zpoixcuypiouqwer";
    4. str.match(reg);
    5. //eg2:
    6. var reg=/[ab][cd][d]/g;
    7. var str="abcd";
    8. str.match(reg);
    9. //eg3:
    10. var reg=/[0-9A-Za-z][cd][d]/g;//相当于var reg=/[0-9A-z][cd][d]/g
    11. var str="ab1cd";
    12. str.match(reg);

    插入符^放到[]里边表示"非"的意思

    1. //eg:
    2. var reg=/[^a][^b]/g;//插入符^放到[]里边表示"非"的意思
    3. var str="ab1cd";
    4. str.match(reg);

    在括号里可以加入"|"表示"或"的意思,"|"操作符两边放匹配规则

    1.     var reg=/(abc|bcd)/g;
    2.     var str="abc";
    3.     str.match(reg);//["abc"];//该规则既能匹配出字符串"abc"
    4.     str="bcd";
    5.     str.match(reg);//["bcd"];//该规则又能匹配出字符串"bcd"
    6.     reg=/(abc|bcd)[0-9]/g;  //匹配规则可以任意组合
    7.     str="bcd2";
    8.     str.match(reg);

    10.1.4 元字符

    元字符是拥有特殊含义的字符,元字符也可以组合放进中括号里去使用,一个元字符代表一位(\d|\D)

    元字符描述
    \w --word查找单词字符(字母+数字+下划线)
    \W查找非单词字符==[^\w]
    \d --data查找数字
    \D查找非数字字符
    \s --space查找空白字符
    \S查找非空白字符
    \b --border匹配单词边界 "today is friday"
    \B匹配非单词边界
    \t查找制表符
    \n查找换行符
    \f查找换页符
    \v查找垂直制表符
    \uXXXX查找以十六进制规定的Unicode字符
    . --必记(点号)查找单个字符,除了换行和行结束符

    "\w"---->[0-9A-z_],(word)单词字符,字母字符

    //eg:
        var reg=/\wcd2/g;
        var str="bcd2";
        str.match(reg);//["bcd2"]
    ​
        //"\W"---->[^\w],即\W是\w的补集
        reg=/\Wcd2/g;
        str.match(reg);
    ​
        str="b*cd2";
        str.match(reg);
    ​
    //若要在正则表达式里匹配反斜杠\,直接写/\/是不行的,需要加上转义字符/\\/

    "\d"---->[0-9]

    //eg:
        //"\D"---->[^\d]
        var reg=/\d\d\d/g;
        var str="123";
        str.match(reg);

    "\s"---->匹配空白字符 ​ 空白字符包括:空格符[ ]、制表符\t、回车符\r、换行符\n、垂直换行符\v、换页符\f

     //附:
        "\S"---->[^\s]

    "\b"---->匹配单词边界(border)

    //eg:
        //"\B"---->非单词边界
        var reg=/\bcde/g;//单词边界后边是cde字符串
        var str="abc cde fgh";
        str.match(reg);
    ​
        str="abc cde fgh";
        reg=/\bcde\b/g;
        str.match(reg);
        
        reg=/\bcde\b/g;
        str="abc cdefgh";
        str.match(reg);
    ​
        str="abc cdefgh";
        reg=/\bcde\B/g;//匹配规则换成\B就可以了
        str.match(reg);

    "\t"---->匹配制表符

    //eg:
        var reg=/\tc/g;
        var str="ab     cde";//c字母前有一个tab键
        str.match(reg);//null,无法匹配视觉效果上的一个tab
    ​
        str="ab\tcde";  
        str.match(reg);//[" c"]
        //即"\t"只能匹配字符"\t",控制台对\t的打印以转义序列制表符"\t"的方式打印
        //所以最后结果是[" c"]
        
    ​
        //其他"\n"、"\f"、"\v"类似于"\t"的使用
        //"."---->[^/r/n],匹配"非"行结束符和换行符

    unicode编码,\uXXXXXX,一般为6位16进制码

    不需要记住哪个字符对应是哪个Unicode编码,要用到的时候可借助“Unicode在线编码转换器”

    //eg:
        var reg=/\u8eab\u4f53\u597d/g;
        var str="身体好";
        str.match(reg);//["身体好"]
    ​
        reg=/[\u4000-\u9000]/g;//也可使用区间去定义规则
        str="身体好";
        str.match(reg);//["身","体","好"]
    ​
        var reg=/[/u0000-/uffff]/g;//能够代表几乎一切字符
        reg=/[\s\S]/g;//这才能够代表匹配一切  

    10.1.5 量词

    量词,代表数量的词(下面表达式的n代表的是一个匹配规则,n后边符号的符号定义量词规则)。

    贪婪匹配。

    量词描述
    n+匹配任何包含至少一个n的字符串                  {1,Infinity}个
    n*匹配任何包含零个或多个n的字符串              {0,Infinity}个
    n?匹配任何包含零个或吗一个n的字符串           0个或1个
    n{X}匹配包含X 个n 的序列的字符串/\w{10}/
    n{X,Y}匹配任何包含X 个至Y 个n 的序列的字符串/\w{6,16}/
    n{X,}匹配包含至少X 个n 的序列的字符串
    n$匹配任何结尾为n 的字符串
    ^n匹配任何开头为n 的字符串
    S(?=n)匹配任何其后紧接指定字符串n 的字符串S abc(?!d)
    S(?!n)匹配任何其后没有紧接指定字符串n 的字符串S
    //eg:   
        var reg=/\w+/g;//匹配\w类的字符出现一次或多次的字符串
        var str="abcvfskhfls";
        str.match(reg);//["abcvfskhfls"],贪婪匹配原则
        
        reg=/\w*/g;//匹配\w类的字符出现零次或多次的字符串
        str="abc";
        str.match(reg);//["abc",""]
        //全局匹配到"abc"之后,逻辑上从那以后还有段距离
        //这段距离符合规则"出现零次或多次的字符串",所以匹配出来一个空字符串
        //贪婪匹配原则
        
        var reg=/\d*/g;
        var str="abc";
        str.match(reg);//["","","",""]
        //该原则对字母a/b/c是无法匹配出来的,所以匹配出空字符串""
        //最后再在最后一个光标位匹配出一个空字符串来,所以一共4个空字符串

    n? ---->0个或1个

    //eg:
        var reg=/\w?/g;
        var str="aaaaa";
        str.match(reg);//["a","a","a","a","a",""],最后还会有一个空字符串""
    ​
    //若要在正则表达式里匹配问号?,直接写/?/是不行的,需要加上转义字符,写成/\?/

    ^n ----> 匹配以n 为开头的字符串n n$ ----> 匹配以n 为结尾的字符串n

    //eg:
        var reg=/ed$/g;//以ed为结尾时匹配
        var str="abcded";
        str.match(reg);//["ed"]
        
        var reg=/^abc$/g;//以该abc开头,且以同一abc为结尾的字符串
        var str="abcabc";
        str.match(reg);//null
    ​
        var reg=/^abc$/g;//以该abc开头,且以同一abc为结尾的字符串
        var str="abc";
        str.match(reg);//["abc"]

    ?=n ----->n只参与条件限定,限定其后紧接指定字符串n 的字符串,但并不参与选择

    ?!n ----->n只参与条件限定,限定其后没有紧接指定字符串n 的字符串,但并不参与选择

    //正向预查  正向断言
        var str="aabaaaa";
        var reg=/aa(?=b)/g;//b只参与条件限定,并不参与选择
        str.match(reg);//["aa"],此时只有一个a 它的后面有紧跟字符b
    ​
        var str="aabaaaa";
        var reg=/aa(?!b)/g;
        str.match(reg);//[aa,aa],此时有4个a 它的后面没有紧跟字符b

    练习一:写一个正则表达式,检验字符串首尾是否含有数字。

    练习二:写一个正则表达式,检验字符串首尾是否含都有数字。

    //答:
        var reg=/^\d|\d$/g;
        var str="123abc";
        str.match(reg);//["1"]
    //答:
    1dgadk3   1
        var reg=/(^\d[\s\S]*\d$|^\d$)/g;
    //[\s\S]指开始与结束字符中间为任意字符,*指出现0到多次
        var str="123abc123";
        str.match(reg);//["123abc123"]

    ####10.2 正则对象方法

    方法描述
    exec寻找字符串中是否含有检测的字符。返回:将找到的字符按数组返回。(execute)
    test检测字符串中是否含有检测的字符。返回:boolean。

    reg.exec(); ---->executive,执行匹配

    //eg:
        var reg=/ab/g;
        var str="abababab";
        reg.exec(str);//["ab"],尽管具有global属性,仍然只返回一个"ab"
        
        //再继续
        reg.exec(str);//["ab"]
        reg.exec(str);//["ab"]
        reg.exec(str);//["ab"]
        reg.exec(str);//null
        reg.exec(str);//["ab"]
        reg.exec(str);//["ab"]
        

    10.3 正则实例属性

    1、ignoreCase 是否设置了i

    2、global 是否设置了g

    3、multiline 是否设置了m

    4、source 字面量形式对应的字符串

    5、lastIndex 开始搜索下一个匹配项的字符位置,默认0

    var reg=/^\d[\s\S]*\d$/g;
    reg.ignoreCase;//false,检测是否含有i 属性
    ​
    reg.global;//true,检测是否含有g 属性
    ​
    reg.multiline;//false,检测是否含有m 属性
    ​
    reg.source;//"^\d[\s\S]*\d$",匹配内容体
    • lastIndex 与exec 方法相搭配使用,查找光标位置

    //eg:
        var reg=/ab/g;
        var str="abababab";
        console.log(reg.lastIndex);//0
        console.log(reg.exec(str));//["ab",index:0,input:"abababab"]
        console.log(reg.lastIndex);//2
        console.log(reg.exec(str));//["ab",index:2,input:"abababab"]
        console.log(reg.lastIndex);//4
        console.log(reg.exec(str));//["ab",index:4,input:"abababab"]
        console.log(reg.lastIndex);//6
        console.log(reg.exec(str));//["ab",index:6,input:"abababab"]
        console.log(reg.lastIndex);//8
        console.log(reg.exec(str));//null
        console.log(reg.lastIndex);//0
        console.log(reg.exec(str));//["ab",index:0,input:"abababab"]
    ​
        //reg.lastIndex是可手动修改的
        reg.lastIndex=0;//reg.lastIndex重置0
        console.log(reg.exec(str));
        //["ab",index:0,input:"abababab"],与上面结果中的index相同
    ​
        //若匹配规则不含有global属性,那在允许exec()方法后lastIndex值始终为0
        var reg=/ab/;
        var str="abababab";
        console.log(reg.lastIndex);//0
        console.log(reg.exec(str));//["ab",index:0,input:"abababab"]
        console.log(reg.lastIndex);//0
        console.log(reg.exec(str));//["ab",index:0,input:"abababab"]
        
    • 补充:"\num" 反向引用,指的是要引用的第num个括号里的表达式值

    //eg1:
        var str="aaaa";
        var reg=/(\w)\1/g;//括号"()"后边的"\1"为反向引用第一个括号的值
        reg=/(\w)\1\1\1/g;//3个"\1"代表后边还要引用第一个括号里的值3次
    ​
    //eg2:
        reg=/(\w)\1\1\1/g;
         str="aaaa";
        str.match(reg);//["aaaa"]
        
        reg=/(\w)\1\1\1/g;
        str="aaaabbbb";
        str.match(reg);//["aaaa","bbbb"]
    ​
        //要匹配"XXYY"格式的字符串
        reg=/(\w)\1(\w)\2/;//"\2"代表引用第二个括号里的值
        str="aabb";
        str.match(reg);//["aabb"]
        console.log(reg.exec(str));//["aabb","a","b",index:0,input:"aabb"]
        //上边结果中的"a","b"是类数组的数据位,即两个"\w"所匹配到的值

    ####10.4 支持正则表达式的String对象的方法

    方法描述
    search检索与正则表达式相匹配的值,返回匹配字符串的位置
    match找到一个或多个正则表达式的匹配
    replace替换与正则表达式匹配的字串
    split把字符串分割为字符串数组

    str.match(reg) ---->在规则中是否含有global 属性时的表现是不同的(与reg.exec(str)的微小区别)

    reg=/(\w)\1(\w)\2/;//无global属性,反向索引
    str="aabbgghh";
    str.match(reg);//["aabb","a","b",index:0,input:"aabb"]
    ​
    reg=/(\w)\1(\w)\2/g;//具有global属性
    str="aabbgghh";
    console.log(str.match(reg));//["aabb","gghh"]

    str.search(reg) ---->匹配后返回的是所匹配字符串的位置,匹配不到时返回-1

    reg=/(\w)\1(\w)\2/g;
    str="edbaabbbbee";
    str.search(reg);
    str.search(reg);//3,与lastIndex无关,只返回第一个符合匹配规则的索引位置
    ​
    reg=/(\w)\1(\w)\2/g;
    str="abc";
    str.search(reg);//-1

    str.split(reg) ---->按照正则表达式拆分字符串

    //eg:
        var str="dai1akhd2gkhs";
        var reg=/\d/g;
        console.log(str.split(reg));//["dai","akhd","gkhs"],即将分隔符两侧的字符串进行拆分
        
        var str="dai1akhd2gkhs";
        var reg=/(\d)/g;//"()"代表记录反向引用,将匹配表达式也返回回来,很少这样用
        console.log(str.split(reg));//["dai","1","akhd","2","gkhs"]
    ​

    str.replace(reg,str1) ---->字符串替换;最实用的方法

    两个参数,参数1放正则表达式,参数2放欲替换成的字符串

    //坑:
        var str="aa";
        console.log(str.replace("a","b"))   //ba,只会替换匹配到的第一个
    ​
        var str="abcdedfa";
        var reg=/a/;
        str.replace(reg,"b");   //ba,跟上边一样没写"g"还是只替换一个
    ​
    //精华:
        var str="abcdedfa";
        var reg=/a/g;
        str.replace(reg,"b");
        //总结:
        //若参数1为字符串(非正则表达式),那将不具有全局替换的能力,只能替换第一个匹配的位置
        //只有正则表达式的global属性才具有全局替换的能力

    出个题玩玩儿,练习一:将但凡匹配"XXYY"格式的字符串均替换成"YYXX"

    //答:
        var reg=/(\w)\1(\w)\2/g;
        var str="aabb";
        str.replace(reg,"$2$2$1$1");//bbaa
        
        //$1代表匹配规则里第一个匹配表达式的值,$2代表匹配规则里第二个匹配表达式的值
        //若要替换成为"$"符号,直接写是不行的,因为它带有语法意义
        //在它前边再加一个$即可达到转义效果,实现用$符进行替换

    再来挑战一下,练习二:将"XYXY"格式的字符串均替换成"YXYX"

    //答:
        var reg=/(\w)(\w)\1\2/g;
        var str="abab";
        str.replace(reg,"$2$1$2$1");//baba

    str.replace(reg,str1) ---->str1的位置还可以放置函数,该函数由系统调用;故可自定义替换格式。

    上面练习一也可以答题如下:

    //答:
        var reg=/(\w)\1(\w)\2/g;
        var str="aabbccdd";
        console.log(str.replace(reg,function($,$1,$2){
            //形参$代表该函数会接受匹配结果,如"aabb"
            //形参$1代表该函数会接收匹配规则里第一个子匹配表达式的匹配结果
            //形参$2代表该函数会接收匹配规则里第二个子匹配表达式的匹配结果
            return $2+$2+$1+$1;
    }))
    //上边函数在返回值时就可以对返回结果进行自定义,如:return $2+$2+$1+$1+"abc".

    再来练习一次,练习三:将"the-first-name"替换成驼峰式写法"theFirstName"

    //答:
        var reg=/-(\w)/g;//能匹配到["-f", "-n"],加括号之后才能使用$1 进行引用
        str="the-first-name";
        console.log(str.replace(reg,"$1"))//thefirstname,还没能转换成大写
    ​
    ​
        console.log(str.replace(reg,function($,$1){
            //function的形参不能只写一个,因为实参是按照顺序传递的
            return $1.toUpperCase();
        }))
        //theFirstName
        //每匹配依次,function执行依次

    10.5 贪婪匹配与非贪婪匹配

    • 贪婪匹配即照着"量词"规则中要求的更多个的情况去做匹配

        var str="aaaaa";
        var reg=/a+/g;
        str.match(reg);//["aaaaa"]
    • 非贪婪匹配,在"量词"规则后边多加一个问号"?"

        var str="aaaaa";
        var reg=/a+?/g;
        str.match(reg);//["a","a","a","a","a"]
    ​
        var str="aaaaa";
        var reg=/a??/g;//第一个问号代表0~1个,第二个问号代表能取0就不取1去做匹配
        str.match(reg);//["","","","","",""]
    ​
        //实用:匹配用双大括号括起来的字符
        var l=/\{\{(.+)\}\}/g;
        var r=/\{\{(.+?)\}\}/g;
        var str=`{{name}}--{{msg}}`
        
        str.match(l);//["{{name}}--{{msg}}"]
        str.match(r);//["{{name}}", "{{msg}}"]

    一定课外多做练习,多做题!!

    补充点好玩儿的练习吧,练习一:

    //题:    
        var str="aaaaaabbbbbbbccccc";
        //将字符串转换成"abc",字符串去重
        
    //答:
        var reg=/(\w)\1*/g;//其中\1*代表反向引用{0,Infinity}个
        console.log(str.replace(reg,"$1"));//"abc"

    来个最有意思,最难的一个练习题,练习二:

    //题:
        var str="100000000000";
        //将数字转换成科学计数法表示,从后往前每隔三位添一个逗号
    ​
    //答:
        //分析1:从后往前查,需要用到结束符,$
        //分析2:结果中,逗号后边的数都将是3的倍数,(\d{3})+
        //分析3:使用正向预查,?=
        //分析4:添逗号,即将空""替换成逗号,所以正向预查前边不写任何东西代表匹配空
        var reg=/(?=(\d{3})+$)/g;
        console.log(str.replace(reg,","));//",100,000,000,000"
        
        //所以要替换的""还要加限定,它后边跟的不能是单词边界\B
        var reg=/(?=(\B)(\d{3})+$)/g;
        console.log(str.replace(reg,","));//"100,000,000,000"

    来点小练习理解(个人推荐直接量)、巩固一下:

    1. 是否带有小数

      var objRegExp= /^\d+\.\d+$/;
      ​
    2. 校验是否中文名称组成

      var reg=/^[\u4E00-\u9FA5]{2,4}$/;
    3. 校验是否全由8位数字组成

      var reg=/^[0-9]{8}$/;
    4. 校验电话码格式

      var reg= /^((0\d{2,3}-\d{7,8})|(1[35847]\d{9}))$/;
    5. 校验邮件地址是否合法

      9391493618639@qq.com

      var reg=/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
  • 相关阅读:
    Vue.js模板语法概述
    武汉新时标文化传媒有限公司短视频的创作和分发
    如何使用 K3s 在您的开发机器上运行 Kubernetes 集群
    设计模式之状态模式
    Django03_Django基本配置
    风向对风力机发电的影响
    python中的none
    js坑之数字型字符串比对只比较第一位数字
    【ACM学习】【STL】关联容器的分类
    HarmonyOS NEXT应用开发之深色模式适配
  • 原文地址:https://blog.csdn.net/qq_52301431/article/details/124991501