美文网首页
js正则表达式入门

js正则表达式入门

作者: 汤吉柯德 | 来源:发表于2020-05-03 19:45 被阅读0次

    1、前言

    正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

    本文就针对正则表达式一般规则做简要介绍,适用于初学者学习细心阅读0.0。

    2、正则表达式

    1. 正则表达式的简介
    正则表达式的一般形式如下,由注释符中间隔开:

    //正则表达式的一般形式
    var reg = /abc/g;       // 全局匹配 abc 字符
    

    正则表达式一般形式包含表达式本体source(代码中的/abc/)和修饰flag(代码中的g),修饰flag紧跟本体source。source属于必需,主要用来匹配对应的特定字符,flag属于非必需,主要用于控制匹配的一些因素,比如是否忽视大小写,多行匹配,全局匹配等。

    正则表达式的创建方式一般有两种,一种通过正则表达式对象是RegExp创建,另一种通过两个/直接创建,一般创建方式如下:

    //通过对象创建
    var reg1 = new RegExp("111");
    console.log(reg1);    // 正则表达式为:/111/
    
    //直接创建
    var reg2 = /222/; 
    

    构造函数RegExp创建,可以接收第二个参数为flag;直接创建法的flag写在最后:

    var reg1 = new RegExp("111","i");    // ignore忽视大小写
    console.log(reg1);    // 正则表达式为:/111/i
    
    //直接创建
    var reg2 = /222/i; 
    

    2. 正则表达式模式
    在掌握基本的正则表达式创建,接下来就要开始了解正则的常用表达式和它的匹配规则了,正则表达式本身定义了很多的有意义的表达式,非常方便简化书写。以下表格列出常用表达式及描述,如下:

    表达式 描述
    /d 数字
    /D 非数字
    /w 字符串和数字和"_"
    /W 非字符串和数字和"_"
    /b 字符串
    /B 非字符串
    /s 空格
    /S 非空格
    n+ 匹配任何包含至少一个 n 的字符串
    n* 匹配任何包含零个或多个 n 的字符串
    n? 匹配任何包含零个或一个 n 的字符串
    [abc] 集合,表示查找方括号之间的任何字符
    [0-9] -可指定范围,这里表示查找从0至9的数字
    (abc) ()分组符,表示将abc捆绑在一起
    (x|y) 查找任何以|分隔的选项
    ^ 在开头表示匹配输入的开始,如果不是在开头表示非
    $ 匹配输入的结束
    . 默认匹配除换行符之外的任何单个字符
    {n} 表示匹配前面字符出现n次
    {n,} 表示匹配前面字符至少出现n次
    {n,m} 表示匹配前面字符出现n到m次

    上面例举了常用正则表达式匹配符号,需要熟记,刚看完可能没有什么感觉,那就实战出真知。

    3. 正则表达式方法
    在实战之前,率先拿好武器,所以先了解正则表达式的匹配方法。正则表达式常用的匹配方法主要有两个,分别是test()和exec();test()方法,接受字符串作为参数,返回boolean,表示匹配是否成功;exec()方法,也接受字符串,返回的是匹配到的结果。

    // test方法,接受一个字符串,匹配成功则返回一个Boolean
    var reg = /abc/i;
    console.log(reg.test("abc"));  //true 返回boolean型
    
    // exec方法,也是接受一个字符串
    console.log(reg.exec("abc"));  // 返回类数组:["abc", index: 0, input: "abc", groups: undefined]
    

    4. 正则表达式的实战练习
    实战开始,话不多说:

    // 匹配数字
    var reg1 = /\d/;   // 或者 reg1 = /[1-9]/
    console.log(reg1.test("123"))  //true
    console.log(reg1.test("abc"))  //false
    //匹配字符串
    var reg2 = /\w/;   // 或者 reg2 = /[a-zA-Z0-9_]/
    // 匹配多个
    var reg3 = /\w+/  //不同于上面,这里可以匹配多个
    
    console.log(reg2.exec("abcd"));    // a 
    console.log(reg3.exec("abcd"));    // abcd
    

    熟能生巧,想必读者正则表达式的基本素养应该有了,那我们稍微再难一丢丢:

    //匹配日期 ,日期年月日,可能隔开有_,-,/三种形式  (\为转义符)
    var reg1 = /^\d{2,4}((\/|\-|\_)\d{1,2}){1,2}$/;  // 年份可以2-4长度,月日1-2长度,可以没有日,隔开符可以/,-,_三种,必须是首尾。
    console.log(reg1.test("1885_8_12"));  // true
    
    // 匹配邮箱
    var reg2 = /^\w+@(\w+\.)+com$/;      // 形似 xxx@xx.xx.com
    console.log(reg2.test("123456@qq.com"));  // true
    
    // 匹配首尾空格
    var reg3 = /(^\s*)|(\s*$)/
    console.log(reg3.test(" / "))  // true
    
    // 匹配url地址
    var reg4 = /^https?:\/\/(\w+\.)+com(\/\w+)*\/?$/;  // 形似 https://xxx.xxx.com/xxx/xxx
    console.log(reg4.test("https://www.baidu.com/xxxx"))  // true
    

    对于()和[]的区别
    ()一般表示匹配的字符组,是捆绑在一起的,需要都符合
    []匹配的集合,集合一般无顺序,相当于每一个等价,有符合就行

    但是()会继续相当于一个正则表达式匹配(看代码)

    var str = 'abcdacd';
    
    //案列一:
    //需要bc两个都有
    str.match(/a(bc)d/g);   //result: [abcd]
    //仅有bc其中一个就可
    str.match(/a[bc]d/g);  //result: [acd]
    
    //案列二:
    //匹配到结果,又将abcd作为输入,bc作为正则表达式,匹配出bc的结果放在了数组后面.
    //即:/bc/.exec('abcd') // result:[bc]
    /a(bc)d/.exec(str);  //result: [abcd, bc]
    
    //[]不会出现再匹配
    /a[bc]d/.exec(str);  //result: [abcd]
    
    //如果不希望出现()的再匹配情况可以使用,非捕获符(?:)
    /a(?:bc)d/.exec(str); //result: [abcd]
    
    

    是不是有点感觉了呢,正则表达式在刚开始的时候可能没有感觉,多加练之后就习惯了。
    如果上面的差不多都掌握了,那么我们继续稍扩充以下正则的规则。

    5. 正则表达式模式二
    继上面常用正则符号,如下是新的表达式:

    表达式 符号
    (?:x) 非捕获括号,匹配 'x' 但是不记住匹配项
    x(?=y) 匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言,也有人称正向查找
    (?<=y)x 匹配'x'仅当'x'前面是'y'.这种叫做后行断言,也有人称反向查找
    x(?!y) 仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找
    (?<!y)x 仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找

    上面的表达式稍微比前面的单个含义难一点,这里需要关联到匹配字符的前面或者后面,先看看理解理解,然后我们继续实战来看看一般如何使用:

    // 匹配前面有a的b字符
    var reg1 = /(?<=a)b/g;  
    console.log("abcbab".match(reg1));    // 输出[b,b]两个b,因为中间的b前面是c无法匹配到
    
    // 匹配后面不是a的b字符
    var reg2 = /b(?!a)/g;
    console.log("bcbabb".match(reg2));   // 输出[b,b,b]三个b中间b后面有a
    

    想必你已经有了大致了解了,因此接下来我们写一个实际运用的小测试:匹配html标签

    // 匹配标签,一般标签都形似<div>前面有"<",后面有">",所以容易想到:
    var reg3 = /(?<=\<)\w+(?=\>)/; 
    console.log("<div>".match(reg3));    // 输出div
    
    // 但是想一想标签不可能这么简单,比如形似:<div class="name"></div> 匹配div上面的方式不可行
    var reg4 = /(?<=\<\/)\w+(?=\>)/;        //由于一般标签存在闭合标签,所以取巧使用闭合标签那部分匹配
    console.log("<div class='name'></div>".match(reg4));      // 输出div
    //但是不是所有都有单独闭合标签,比如形似<image id='id' src='./' />这种形式上面就又不可以了
    
    var reg5 = /(?<=\<)\w+(?=\s)/;   //观察发现标签前面为<后面为空格,因此取其中得到标签
    console.log("<image id='id' src='./' />".match(reg5)); 
    
    
    //综合上面,我们将两者合在一起
    var reg6 = /(?<=\<)\w+(?=\s|\>)/;      //使用或|
    console.log("<image id='id' src='./' />".match(reg6));   // image
    console.log("<div class='name'></div>".match(reg6));   // div
    console.log("<div>".match(reg6));  // div
    

    好的单个标签的匹配就讲到这里不再继续深入,转而,既然我们能够匹配标签了,那么标签里的内容是不是也就能够获取了呢?

    //立刻想到
    var reg1 = /(?<=\>)\w+(?=\<\/)/       //<>符号与上面匹配标签时相反,因为数据前面为>,后面为<
    console.log("<div>xxx</div>".match(reg1));  // 返回xxx
    
    // 对于标签嵌套,形似<div><div>xxxx</div><div>xxxxx</div></div>匹配
    var reg2 = /(?<=\>)\w+(?=\<\/)/g;     //加个全局匹配
    console.log("<div><div>xxxx</div><div>xxxxx</div></div>".match(reg2));   // ["xxxx","xxxxx"]
    

    感兴趣的小伙伴可以继续深入其他情况,强大的Vue的编译方式也是使用了大量的正则来匹配标签变量的,要复杂的多,只是本文仅对一般形式做出匹配,不再深入。

    6. 可操控正则表达式的一般使用方法
    在基本了解正则之后,就要使用正则了,因此列举常用有关正则的方法。
    前面已经提到过正则的方法常用有两个,这里再次列举出来:

    //返回一个boolean,匹配到则返回true,未匹配到返回fasle
    reg.test("string");
    
    //返回第一个被匹配到的字符串。包括下标,输入内容
    reg.exec("string")
    

    然后还有,字符串的方法,可以以正则表达式作为参数的方法,常用有四个:

    //字符串拆分可接受正则
    str.split();
    //匹配可接受正则
    str.match();
    //替换可接受正则
    str.replace();
    //寻找可接受正则
    str.search();
    
    //示例
    var str = "abcda";
    var reg = /a/g;
    var s = str.replace(reg, "z");
    console.log(s);  // zbcdz
    

    7. 关于正则lastIndex的小细节
    一个需要注意的细节,正则表达式有一个lastIndex的属性值,表示正则表达式匹配的开始下标位置,即正则表达式匹配的开始位置。先上代码,看以下的情形:

    //实例一
    var reg1 = /a/g;
    var str1= "abc"
    reg1.test(str1); //true    
    console.log(reg1.lastIndex); // 1
    reg1.test(str1); //false ,再次匹配居然false
    
    //实例二
    var reg = /1/g;
    var str = "123123";
    reg.lastIndex = 2;
    reg.exec(str);    // 返回的下标为3,居然而不为1,因为字符匹配的起始位置被设定为了2;
    

    在有全局搜索时(正则有g修饰符),搜索的起点由lastIndex表示(初始lastIndex为0),所以会出现上面两次执行test第二次居然失败的问题,因此处理方式是当执行一次搜索后,将lastIndex置零就可以。

    var reg1 = /a/g;
    var str1= "abc"
    reg1.test(str1); //true    
    reg1.lastIndex = 0
    reg1.test(str1); //true   返回true因为从头匹配。
    

    8. 常用的正则表达式
    本文末尾例举一些常用的正则表达式,以供方便查阅使用,不过既然授之以渔,查阅的就不多写了:

    需求 表达式
    匹配正数,负数,小数 /^(-|+)?\d+(.\d+)?$/
    匹配汉字 /^[\u4e00-\u9fa5]{0,}$/
    匹配邮箱 /^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$/
    匹配网址 /[a-zA-z]+://[^\s]/ 或 /^http://([\w-]+.)+[\w-]+(/[\w-./?%&=])?$/
    匹配身份证 /^\d{15}|\d{18}$/
    匹配强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间) /^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$/
    匹配日期格式 /^\d{4}-\d{1,2}-\d{1,2}/
    匹配IP地址 /\d+.\d+.\d+.\d+/

    .......

    9. 尾语
    本文介绍了正则的一般使用,如有错误,望请指正!欢迎转载,转载前请先联系作者,谢谢!

    相关文章

      网友评论

          本文标题:js正则表达式入门

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