美文网首页
第三十三节: JavaScript 正则表达式

第三十三节: JavaScript 正则表达式

作者: 心存美好 | 来源:发表于2022-02-16 10:48 被阅读0次

    1. 理解转义

    转义即转换意义,改变意义

    1. 转义符号 \
    2. 转义字符 \字符( 把原有的字符转换意义)
      <p id="box"></p>
      <script>
        var str = '你是很"牛逼"的一个人'
        // 如果我就想包裹单引号
        var str = '你是很'牛逼'的一个人'
        // 直接只用发现牛逼会变成一个变量,变量和字符串这么拼接就是错的
    
        var str = '你是很\'牛逼\'的一个人'
        // \' 就是转义字符   把有意义的符号转成普通符号
    
        //同样的\ 代表转义,那么我就想在网页中显示\ 就可以用转义
        var str = '你是很\\牛逼\\的一个人'  //把普通符号转为有意义的符号
        box.innerHTML = str;
      </script>
    
    一些规定好的转义字符 :\n 换行 \t 制表符 \r 回车

    2. 正则表达式

    2.1 什么是正则表达式

    正则表达式是字符串的一种匹配模式,专门为简化字符串操作而生。就是为了检索字符串中特定字符的规则,正则并不是单纯的字符串,而是一种逻辑公式

    2.2. 创建正则表达式

    创建正则的两种方式

    1. 通过构造函数创建 var reg = new RegExp();

    2. 字面量的方式创建 var reg = / /;

    2.2.1 构造函数创建正则
    console.log(RegExp);   //ƒ RegExp() { [native code] }
    //构造函数创建正则
    let regExp = new RegExp(); //没有传参的结果/(?:)/
    console.log(regExp)  
    
    let regExpa = new RegExp('a');//要匹配字符a  结果/a/
    console.log(regExpa)  
    
    let str='abcadefgha'
    console.log(str.includes('a'))//之前写法 判断字符串中是否含有a
    console.log(str.match(regExp))  //使用正则判断是否含a
    console.log(str.split(regExpa))//正则切割字符串
    

    js给我们提供了一个内置构造函数用来创建正则 RegExp

    RegExp 其实是由两个单词构成的(大驼峰方式)

    regular expression 正规的表达式

    正则表达式是一个通过内置的构造函数构造出来的对象

    var reg = new RegExp('text');  // 实例化一个正则对象
    
    构造函数参数
    1. 第一参数是正则
    2. 第二个参数是修饰符 i g m
    var reg = new RegExp('text');  // 实例化一个正则对象
    var str = 'This is a text';
    console.log(reg.test(str));   // true;
    // test()方法就是以正则为规则检查字符串中是否包含正则内容
    
    2.2.2 .字面量(直接量)创建正则
     let reg = /a/ig;  //两个/之间必须有匹配的内容,没有内容就成了js的单行注释
        console.log(reg); 
        console.dir(reg);   //按对象的方式打印正则,就可以看到正则的属性   此时flags: "gi",i g参数都是true。原型上有一些方法
    
    2.2.3 正则使用注意

    这两种方式我们使用哪一种,按照以往的经验,推荐使用字面量的方式

    但是有的时候只能使用构造函数,比如变量

    var v = 'text';
    var reg = /v/;            // 这样写正则就匹配v了
    var reg = new RegExp(v);  // 所以这种情况就只能用构造函数方法了
    
    2.3.1 test

    正则对象的一个方法,它表示该字符串(参数)是否匹配我们的正则规则。

    使用方式 reg.test(str)

    参数 str: 是需要查询(匹配)的字符串

    返回值

    布尔值,匹配成功返回true,否则返回false

    var reg = /text/;
    var str = 'This is a text';
    console.log(reg.test(str));   // true;
    // test()方法就是以正则为规则检查字符串中是否包含正则内容
    
    //test方法
        let reg = /a/ig;
        let str = 'fasfgggggggfgdfwrewfdfsfaga';
        let res = reg.test(str)//正则调用方法操作字符串
        console.log(res);
        if (res) {
          console.log('匹配成功' + res)
        } else {
          console.log('匹配不成功' + res)
        }
    //之前用str.search('a')   、   str.indexOf('a',8)可以指定开始的位置
    
    2.3.2 exec

    提取匹配成功的子字符串

    使用方式 reg.exec(str)

    参数 str: 是需要查询(匹配)的字符串

    返回值 布尔值

      //exec方法
        let reg = /t(ed)d/g;
        let str = 'fasfgggggteddggfgdfwreteddwfdf steddfaga';
        let res = reg.exec(str)
        console.log(res);
        let res2 = str.match(reg)   //1、如果正则没有属性g,两个方法的结果一样。正则加了属性match方法就会全局匹配。2、不加全局匹配,子项ed都会匹配
        console.log(res2)
    
    var reg = /wuwei/g;
    var str = 'hello wuwei wuwei aaa';
    // 判断str字符串是否匹配我们reg规则
    console.log(reg.exec(str));
    // ["wuwei", index: 6, input: "hello wuwei wuwei aaa", groups: undefined]
    

    字符串的match方法也能实现相同的功能

    var reg = /wuwei/g;
    var str = 'hello wuwei wuweiaaa';
    // 判断str字符串是否匹配我们reg规则
    console.log(str.match(reg)); //如果正则没有属性g,两个方法的结果一样。正则加了属性match方法就会全局匹配
    // ["wuwei", "wuwei"]
    
    2.3.3 可以使用正则的字符串方法
    1. search 获取字符在字符串中的位置
    2. split 字符串转化成数组
    let reg =/a/;   
    var str = 'Thisaisabtext';
    console.log(str.split(reg));    //字符串方法使用正则
    
    1. replace 字符串替换
    2.4. 修饰符
    1. i 表示不区分大小写 ignoreCase
    2. g 表示全局匹配 global
    3. m 表示换行匹配 multiline
    2.4.1 不区分大小写
    //  区分大小写
    var reg = new RegExp('Text');  // 实例化一个正则对象
    var str = 'This is a text';
    console.log(reg.test(str));   // false;
    
    // 不区分大小写
    var reg = new RegExp('Text','i');  // 实例化一个正则对象
    var str = 'This is a text';
    console.log(reg.test(str));   // true;
    
    let reg =new RegExp('A','i');//第二个参数i是修饰符,表示特殊意义的不区分大小写。两个参数都要加引号,不加引号的是变量
    var str = 'Thisaisabtext';
    console.log(str.split(reg));
    
    2.4.2全局匹配

    默认值匹配一个

    // 不加全局匹配
    var reg = new RegExp('text');  // 实例化一个正则对象
    var str = 'This is a text and text and text';
    console.log(str.match(reg));
    // ["text", index: 10, input: "This is a text and text and text", groups: undefined]
    
    // 加全局匹配修饰符
    var reg = new RegExp('text','g');  // 实例化一个正则对象
    var str = 'This is a text and text and text';
    console.log(str.match(reg));
    // ["text", "text", "text"]
    
    let reg =new RegExp('a','g')//如果加了参数g,表示全部匹配万
    var str = 'Thisaisabtext';
    console.log(str.match(reg)); //match天生的方法只匹配第一个,成功就不会再往后匹配了,结果中0为匹配的值,2得到的索引,3为原来的字符串
    

    2.4.3 多行匹配

        let reg = new RegExp('^a', 'm')//^表示匹配第一个字符必须是a,以a开头   
        var str = 'Thisai\nabtex\nt\naad';  //加了\n\r控制台中是换行的,表示保留的是老式打印机的换行并回到左侧原理,只写/n也可以
        console.log(str)   
        console.log(str.match(reg))  //正则默认匹配一行,只匹配一个,如果加上m就可以多行匹配了。修饰符'img'全写,表示不区分大小写,全局多行匹配
    
    var reg = new RegExp('^Text');  // 实例化一个正则对象
    var str = 'This is a \nText and';
    console.log(str.match(reg));  // null
    
    // 多行匹配
    var reg = new RegExp('^Text','m');  // 实例化一个正则对象
    var str = 'This is a \nText and';
    console.log(str.match(reg));// ["Text", index: 11, input: "This is a ↵Text and", groups: undefined]
    

    字面量使用修饰符

        let reg = /a/i  // 斜杠里面表示规则,外面是修饰符
        var str = 'ThisaiAb\n extad'; 
        console.log(str)
        console.log(str.match(reg)) 
    

    3. 正则表达式的特殊语法

    3.1. 特殊字符

    正则表达式由普通字符和特殊字符(元字符)组成。

    普通字符包括:字母(abcABC),数字(123),_等等

    特殊字符:() [] {} ^ $ * ? \ | + .

    普通字符我们可以直接拿来用,但是,特殊字符是一定要转义。因为特殊字符在正则中有特殊的意义

    // 匹配 ^a
    var reg = /\^a/
    console.log(reg.test('bb^acc'))
    
    // 匹配\m
    var reg = /\\m/;    // 特殊字符要转义
    console.log(reg.test('asdf\\msadfasd'));    // 字符串中反斜杠要转义
    
    var reg = /\^a/   //匹配^a开头的字符串
    var reg1 = /^a/   //匹配以a开头的字符串
    let str='bb^acc'
    console.log(reg.test(str))
    console.log(reg1.test(str))
    
    3.2. 预定义的特殊字符

    \t /\t/ 制表符

    \n /\n/ 回车符

    \f /\f/ 换页符

    \b /\b/ 与回退字符

    // 匹配制表符
    var str = 'a  b';
    var reg = /\t/;
    console.log(reg.test(str));
    
    // 匹配回车符
    var str2 = `a\nb`;
    var reg2 = /\n/;
    console.log(str2)
    console.log(reg2.test(str2));
    
    3. 3字符集

    Javascript的正则表达式中有四类字符集

    3.3.1 简单类

    它是有一一对应的字符组成的集合,通过[]包裹住,来表示这几个字母组成的一个集合

    如: [abDF45]表示由abDF45六个字符组成的一个集合

    let str ='ab1cd2ef3gh4ij5k'
    let reg =/[123]/  //匹配集合中的任意个都可以
    console.log(str.split(reg));//正则切割字符串  ["ab", "cd", "ef", "gh4ij5k"]
    
    //取出来字符 123jk
    let str ='ab1cd2ef3gh4ij5k'
    let reg =/[5123jk]/g  //匹配集合中的任意个都可以
    console.log(str.match(reg));//正则切割字符串
    
    var str = 'abcdefg';
    var reg = /[dqqqqqq]/;
    console.log(reg.test(str));
    
    3.3.2 范围类

    通过首尾字母以及-组成的一个范围集合

    如:[a-z] 表示小写字母集合。[A-Z] 表示大写字母集合。[0-9] 表示数字集合。[i-y] 表示小写字母i到y的集合

    let str ='ab1cd2ef3gh4ij5k'
    let reg =/[abcdefghijklmnopq]/g  //匹配集合中的任意字符可以改成范围[a-z]
    console.log(str.match(reg));
    
    var str = 'abcdeg';
    var reg = /[f-i]/;
    console.log(reg.test(str));
    
    var str = 'abci69dAeg';
    var reg = /[f-iea-cA-Z0-9]/g;//多个范围字符集
    console.log(str.match(reg))
    

    按照字符编码集可以从小到大[A-z] 不能从大到小[a-Z],这样写及容易报错

    3.3.3 负向类:就是取反的意思

    通过在集合[]内部最前面添加^来表示不包含该集合的字符集

    如:[abc]表示不包含abc的任意字符集合,[ab89CD] 表示不包含ab89CD这六个字符的集合

    var str = 'fabcdef';
    var reg = /[^f]/g;
    console.log(str.match(reg))
    console.log(reg.test(str));
    
    3.3.4 组合类

    通过[]将几个集合拼接在一起表示一个组合的集合。

    如:[a-zA-Z0-9] 表示大小写字母以及数字的结合

    var str = '054645756gjhjhkjhljklA';
    var reg = /[0-9a-z]/g;
    console.log(reg.test(str));
    console.log(str.match(reg))
    
    3.3.5 注意
    1. 中括号的字符集里面无论你写多少个字符只会匹配其中一个
    2. 特殊中文字符集的匹配
    var str = '054乐64我57喜56欢gjh音jhkjhljklA';
    var reg = /[\u4e00-\u9fa5]/g;  //中文集
    console.log(str.match(reg))
    console.log(str.match(reg).join(''))
    
    3.4. 界定符

    字符串是有边界,这里的边界指的就是字符串的首尾

    3.4.1 界定字符的首尾

    字符串的起始位置我们用^,

    如: /^abc/ 判断字符串是否是以abc开始的

     //判断是不是以http开头
    var url = 'http://www.baidu.com/httpsfds/';
    var reg = /^http/; 
    console.log(reg.test(url))//判断是否匹配成功
    console.log(url.match(reg))
    

    字符串的结束位置我们用$表示

    如:/xyz$/ 判断字符串是否是以xyz结尾的

    //判断图片是否以jpg结尾
    var img = 'http://www.baidu.com/xx/aa.jpg';
    var reg = /jpg$/;
    console.log(reg.test(img))
    
    //判断正则是否等于字符串,首位的界定
    var str = 'aabb';
    var reg = /^aabb$/;
    console.log(reg.test(str))
    
    3.4.2 匹配后面跟的字符

    (?=n) 匹配到后面紧跟着字符n的字符
    (?!n) 匹配到后面没有紧跟着字符n的字符

    let str ='abacagacajdfad';
    let reg =/a/g;
    console.log(str.match(reg));//将所有的a取出来
    let reg1 =/a(?=c)/g;//只要a后面是c的a
    console.log(str.match(reg1))
    let reg2 = /a(?!c)/g   //只要a后面不是c的a
    console.log(str.match(reg2))
    
    
    3.5. 预定义的类(元字符)

    就是特殊的转移字符,把一些字母转成特殊意义的字符

    . [^\n\r] 除了换行和回车之外的任意字符

    \d [0-9] 数字字符

    \D [^0-9] 非数字字符

    \s [ \t\n\f\r ] 空白字符(换行、制表等)

    \S [^ \t\n\f\r ] 非空白字符

    \w [a-zA-Z0-9_] 单词字符(所有的字母)

    \W [^a-zA-Z_0-9] 非单词字符

    let str ='abac#$aga\nca\rjdfad';
    let reg =/./g;  //除了换行符和回车的字符,等价于 let reg =/[^\n\r]/g
    console.log(str.match(reg))
    
    let str ='a1b2c*#3@d4';
    let reg =/\d/g;  //匹配数字  等价于reg= /[0-9]/g
    console.log(str.match(reg))  
    let reg1 = /\D/g  //除了数字  等价于reg1 = /[^0-9]/g
    console.log(str.match(reg1))
    
    let str ='a 1b\t2\nc\f*#\r3';
    let reg =/\s/g;    //空白字符  reg = /[ \t\n\f\r]/g  
    console.log(str.match(reg)) 
    let reg1 = /\S/g  // 非空白字符   reg1 = /[^ \t\n\f\r]/g
    console.log(str.match(reg1))
    
    let str ='abFDE234_%$@';
    let reg =/\w/g;    //字符  等价于/[a-zA-Z0-9_]/g
    console.log(str.match(reg)) 
    let reg1 = /\W/g  // 非字符   等价于/[^a-zA-Z0-9_]/g
    console.log(str.match(reg1))
    
    3.6. 量词

    无论字符集还是元字符,每次都只能匹配到一个字符,无法匹配多个字符,所以引入量词的概念,用来设置匹配到字符的个数

    匹配的原则符合贪婪匹配原则,即尽可能多的匹配,可以在量词后面加上?,能够取消贪婪匹配

    重复书写某个规则时可以用量词代替,比如需要重复匹配10个数字,可以由/\d\d\d\d\d\d\d\d\d\d/改为/\d{10}/的写法。

    let str ='abFDE234a34567b';
    let reg =/\d/g;    //每次匹配一个字符(3) ["2", "3", "4"]
    let reg1 =/\d\d\d/g;   
    let reg2 =/\d{3}/g;    //量词的关键符号是大括号  固定的数字个数
    console.log(str.match(reg)) 
    console.log(str.match(reg1)) 
    console.log(str.match(reg2)) 
    
    let str ='a1aaa23';
    let reg =/[\da]/g; 
    console.log(str.match(reg)) 
    
    2.6.1 量词普通写法

    {n} n个

    {n,m} n~m个,包含n也包含m

    {n,} n~无穷大个,包含n

    //几个数字切割字符串   
    let str ='ab12FDE3b2347bd33335dbre';
    let reg =/\d/g; 
    let reg1 =/\d\d/g;   
    let reg2 =/\d{1,5}/g;  //2个,3个,4个的都可以匹配成功 2-5s这个范围内就行
    console.log(str.split(reg)) 
    console.log(str.split(reg1)) 
    console.log(str.split(reg2)) 
    
    //第二个数空着,表示匹配的数量是2 - +正无穷   
    let str ='ab12FDE3b2347bd33335db12345678re';
    let reg =/\d{1,}/g;  //匹配的数量是2-正无穷  
    console.log(str.split(reg)) 
    
    3.6.2 量词特殊写法(量词的简写)

    {1,} 可由 + 代替

    {0,} 可由 * 代替

    {0,1} 可由 ? 代替

    let str ='ab12FDE3b2347bd33335db12345678re';
    let reg =/\d+/g; //1到正无穷次
    console.log(str.split(reg)) 
    
    let str ='ab1dddFD0er0';  
    let reg =/\d?/g; //匹配0次或一次   /\d{0,1}/g
    console.log(str.split(reg)) 
    
    let str ='ab1FD023er0';  
    let reg =/\d*/g; //匹配0次到无穷次
    console.log(str.split(reg)) 
    
    3.6.3 贪婪与惰性

    量词+默认贪婪匹配,就是说尽量往指定范围类最大的匹配,在量词后面加上 ? 符号,变为惰性匹配,也就是尽量少的去匹配。

    3.7. 子项
        //匹配出来手机号码
        let str = '小明:12345678654';
        let reg = /\d{11}/g
        console.log(str.match(reg)) //字符方法串匹配出来
        console.log(reg.exec(str))//正则的方法匹配出来
    
        //匹配出来手机号码,减少量词个数的写法
        let str = '小明:15345678654';
        let reg = /1[358]\d{9}/g   //手机号码第一位位1,第二个位是集合中的358之一
        console.log(str.match(reg)) 
    
        //保证匹配11位的手机号码
        let str = '15345678654';
        let reg = /^1[358]\d{9}$/g   //首尾^$  数字多了就为null
        console.log(str.match(reg)) 
    

    定义正则时,可以用()将部分规则包裹起来,这样在使用match或者exec做匹配的时候,能在得到的结果里面拿到该部分匹配的内容。

        //把子项的值单独抽离出来
        let str = 'xiaoming:15345678654';
        let reg = /(\w+):(1[358]\d{9})/g   //加了小括号就可以把xiaoming 和手机号码分出来。xiaoming可以用\w+代替
        let result = reg.exec(str)
        console.log(result[1]) 
        console.log(result[2]) 
    
    var str = "abcd1245ef";
    var reg = /d(\d+)/;
    console.log(str.match(reg));
    console.log(str.match(reg)[1]);
    

    注意一点加全局匹配g ,match方法就不包含子项了

    3.7.1 子项反项引用

    也叫捕获组

        //子项的反引用
        let str = 'abcdbdbdaaaeefefef';
        let reg = /(\w{2})\1/g   //   \1代表把第一个子项规则再使用一遍
        console.log(str.match(reg))
    
        //子项的反引用
        let str = 'ababedbdbedw3aaaeefefefe';
        let reg = /(\w)(\w)\1\2/g //   \1 代表把第一个子项规则再使用一遍  \2代表把第二个子项再使用一遍
        console.log(str.match(reg))
    
    var str = "ccsdbbcc99d";
    var reg = /([a-z])\1/g;
    console.log(str.match(reg));
    
    3.8. 或者 |

    在正则中 | 表示或者

    var str = "ccsdbbcc99d";
    var reg = /[acb]/g;    //字符集[]就是或者的意思
    console.log(str.match(reg));
    
    var str = "ccsdbbcc99d";
    var reg = /a|c|b/g;    //使用或者代替字符集
    console.log(str.match(reg));
    
    var str = "adcd12ef";
    var reg = /ad|cd/g;
    console.log(str.match(reg));  // ["ad","cd"]
    

    可以与子项结合使用

    var str = "adcd12edf";
    var reg = /(a|c|e)d/g;
    console.log(str.match(reg));  // ["ad","cd"]
    

    如果或者放在字符集里面就只是表示普通的竖线

    jvar str = "adcd12ed|df";
    var reg = /[a|ce]d/g;    //集合中的竖线会被匹配到,不是或者的意思
    console.log(str.match(reg));  //  ["ad", "cd", "ed", "|d"]
    
    例子
    //匹配邮箱
    str = "fsfdsf@qq.com"
    let reg =/(\w+)@\w{2,}\.[a-zA-Z]{2,}/    //点号有特殊意思所以需要转义
     console.log(reg.test(str)); 
     console.log(reg.exec(str)[1]); //如果有子项就要用正则的exec方法
    
    // 验证手机号
    /**
     * 11位 {11}
     * 第一位是1 ^1
     * 都是数字 [0-9] \d
     */
    var reg = /^1\d{10}$/;
    var str = prompt('请输入手机号');
    if (reg.test(str)) {
        alert('成功')
    } else {
        alert('失败');
    }
    

    相关文章

      网友评论

          本文标题:第三十三节: JavaScript 正则表达式

          本文链接:https://www.haomeiwen.com/subject/cogrlrtx.html