zoukankan      html  css  js  c++  java
  • JS正则表达式的创建、匹配字符串、转义、字符类、重复以及常用字符

    正则表达式都是操作字符串的

    作用:对数据进行查找、替换、有效性验证


    创建正则表达式的两种方式:

    // 字面量方式
    /js/
    
    // 构造函数方式
    regular expression
    new RegExp()

    普通字符:字母 数字 汉字 _ 空格 ; , @ (没有特殊含义的符号)


    两种匹配的方式:

    test 测试,找到返回true,反之为false

    exec 匹配字符,找到的话就返回该字符(以数组形式),反之返回null

    这两个都是属于正则的方法,所以前面是跟的正则

    var str="i love js";
    var pattern=/js/;
    console.log(pattern.test(str));//true
    console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]
    
    var pattern=/Js/;
    console.log(pattern.test(str));//false
    console.log(pattern.exec(str));//null

    正则默认情况下是区分大小写的

    使用模式修饰符可以设置不区分大小写


    三种模式修饰符:

    i  ignoreCase  忽略大小写

    g  global  全局匹配

    m   multiline  多行匹配

    var str="i love js";
    
    var pattern=/Js/i;
    console.log(pattern.test(str));//true
    console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]

     i g m这三个模式修饰符可以任意组合,无顺序要求

    var str="i love js";
    
    var pattern=new RegExp("js");
    console.log(pattern.test(str));//true
    console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]
    
    var pattern=new RegExp("Js");
    console.log(pattern.test(str));//false
    console.log(pattern.exec(str));//null
    
    var pattern=new RegExp("Js","i");
    console.log(pattern.test(str));//true
    console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]

    字面量方式与构造函数方式的区别:

    /js/i   直观简洁

    new RegExp("js", "i")  可以由于变量的检测

    var str="i love js";
    
    var userInput="js";//需要匹配的字符在变量中
    var pattern=/userInput/i;//该方式不可取,直接匹配的是userInput
    console.log(pattern.test(str));//false
    console.log(pattern.exec(str));//null
    
    var userInput="js";//需要匹配的字符在变量中
    var pattern="/"+userInput+"/i";//该方式不可取,正则变为了字符串,不再具有test和exec方法
    console.log(typeof pattern);//string 
    console.log(pattern.test(str));//报错
    console.log(pattern.exec(str));//报错
    
    var pattern=new RegExp(userInput,"i");
    console.log(typeof pattern);//object 正则属于正则对象
    console.log(pattern.test(str));//true
    console.log(pattern.exec(str));//["js", index: 7, input: "i love js", groups: undefined]

    简单的转义字符

    / 表示正则的边界,匹配时需要进行转义

            var str="//我是注释";
            var pattern=////;
            console.log(pattern.exec(str));// ["//", index: 0, input: "//我是注释", groups: undefined]

    字符串中如果存在 ,默认会对下一个字符进行转义,如果需要作为普通字符处理,就对转义字符 再进行转义处理 \ 

        var str="\\";
        console.log(str);// 结果只显示\

    普通字符加上 可能会有特殊含义

    如 代表换行

        var str="nba";
        var pattern=/n/;
        console.log(pattern.exec(str));//匹配n  ["n", index: 0, input: "nba", groups: undefined]
    
        var pattern2=/
    /;
        console.log(pattern2.exec(str));//匹配换行符  null

    匹配 tab键

        var str="    hello";
        var pattern=/	/;
        console.log(pattern.exec(str));//匹配n  ["    ", index: 0, input: "    hello", groups: undefined]

    可以用 ascii码 来正则匹配字符

        var str="hello
    cyy";
        var pattern=/x0A/;
        console.log(pattern.exec(str));//匹配
      ["↵", index: 5, input: "hello↵cyy", groups: undefined]

    可以用 unicode 编码来正则匹配字符

        var str="    前面是tab键";
        var pattern=/u0009/;
        console.log(pattern.exec(str));//匹配tab键  ["    ", index: 0, input: "    前面是tab键", groups: undefined]

    unicode 常用于匹配汉字

    匹配一个字符串中的所有中文:u4e00-u9fa5

        var str="i am 陈莺莺";
        var pattern=/[u4e00-u9fa5]/;
        console.log(pattern.exec(str));//匹配中文  ["陈", index: 5, input: "i am 陈莺莺", groups: undefined]

    可以匹配换行符的有:     x0A   u000A


    字符类

    [ ] 匹配中间的任意一个字符

        var str="javascript";
        var pattern=/[js]/;
        console.log(pattern.exec(str));//匹配j  ["j", index: 0, input: "javascript", groups: undefined]

    [^ ]  表示取反

        var str="javascript";
        var pattern=/[^js]/;//匹配除了j和s之外的
        console.log(pattern.exec(str));// ["a", index: 1, input: "javascript", groups: undefined]

    [ ] 中间可以是一个范围

        var str="javascript";
        var pattern=/[k-z]/;//匹配k-z之间的字母
        console.log(pattern.exec(str));// ["v", index: 2, input: "javascript", groups: undefined]

    表示范围时,前面的必须小于等于后面的

        var str="javascript";
        var pattern=/[c-c]/;//前面等于后面
        console.log(pattern.exec(str));// ["c", index: 5, input: "javascript", groups: undefined]
    
        var pattern2=/[c-b]/;//前面大于后面
        console.log(pattern2.exec(str));// 报错

    同时匹配大小写字母

        var str="JavaScript";
        var pattern=/[a-zA-Z]/;//前面等于后面
        console.log(pattern.exec(str));// ["J", index: 0, input: "JavaScript", groups: undefined]

    匹配所有数字 0-9

        var str="JavaScript3333";
        var pattern=/[0-9]/;
        console.log(pattern.exec(str));// ["3", index: 10, input: "JavaScript3333", groups: undefined]

    [ ] 中间可任意组合,如

    [a-zA-Z0-9@_]


    常用的字符类:

    . 匹配所有除了 之外的字符

        var str="3.14";
        var pattern=/./;
        console.log(pattern.exec(str));// ["3", index: 0, input: "3.14", groups: undefined]

    如果单纯匹配 .  转义即可

        var str="3.14";
        var pattern=/./;
        console.log(pattern.exec(str));// [".", index: 1, input: "3.14", groups: undefined]

    . 不能匹配换行符

        var str="
    ";
        var pattern=/./;
        console.log(pattern.exec(str));// null

    数字字母下划线

    /[a-zA-Z0-9_]/      =    /w/

    /[^a-zA-Z0-9_]/    =   /W/

        var str="@_";
        var pattern=/w/;
        console.log(pattern.exec(str));// ["_", index: 1, input: "@_", groups: undefined]

    数字

    /[0-9]/   =   /d/

    /[^0-9]/   =  /D/

        var str="@_123";
        var pattern=/d/;
        console.log(pattern.exec(str));// ["1", index: 2, input: "@_123", groups: undefined]

    / /  匹配空格

    /  / 匹配 tab

    /s/  匹配空格或者制表符(tab)

    /S/  匹配除了空格或者制表符之外的其他字符


    匹配的顺序取决于字符串中的顺序

        var str="    9";
        var pattern=/[ds]/;
        console.log(pattern.exec(str));// ["    ", index: 0, input: "    9", groups: undefined]

    重复

    {n} 表示量词,出现 n 次

        var str="123456789";
        var pattern=/d{3}/;//匹配3个数字
        console.log(pattern.exec(str));// ["123", index: 0, input: "123456789", groups: undefined]

    {n1, n2} 表示出现次数大于等于n1,小于等于n2

        var str="123456789";
        var pattern=/d{2,3}/;//匹配2-3个数字,会尽可能多的匹配
        console.log(pattern.exec(str));// ["123", index: 0, input: "123456789", groups: undefined]

    {n1, } 表示大于等于n1

    { ,n2 } 不表示小于等于n2,这种写法是错误的

        var str="123456789";
        var pattern=/d{1,}/;
        console.log(pattern.exec(str));// ["123456789", index: 0, input: "123456789", groups: undefined]
    
        var pattern2=/d{,2}/;//这种写法是错误的
        console.log(pattern2.exec(str));// null

    ?   =  {0,1}  匹配0次或者1次

        var str="123456789";
        var pattern=/d?/;
        console.log(pattern.exec(str));// ["1", index: 0, input: "123456789", groups: undefined]

    +  =  {1,}  至少1次

        var str="123456789";
        var pattern=/d+/;
        console.log(pattern.exec(str));// ["123456789", index: 0, input: "123456789", groups: undefined]

    *  =  任意次(包括0次)

        var str="123456789";
        var pattern=/d*/;
        console.log(pattern.exec(str));// ["123456789", index: 0, input: "123456789", groups: undefined]

    匹配价格

        var str="肯德基豪华午餐¥15.5元";
        var pattern=/d+.?d*/;
        //前面的数字 至少有1位
        //. 出现0次或者1次
        //后面的数字 可以有也可以没有,任意次
        console.log(pattern.exec(str));// ["15.5", index: 8, input: "肯德基豪华午餐¥15.5元", groups: undefined]

    匹配正整数和负整数

        var str="肯德基豪华午餐¥15.5元";
        var pattern=/-?[1-9]d*/;
        var pattern=/-{0,1}[1-9]d*/;

    非贪婪的重复

    正则匹配默认是贪婪模式,存在量词时会尽可能多的匹配

        var str="aaab";
        var pattern=/a+/;
        console.log(pattern.exec(str));//["aaa", index: 0, input: "aaab", groups: undefined]

    在量词后面加上 ?  ,表示由贪婪模式转为非贪婪模式,尽可能少的匹配

        var str="aaab";
        var pattern=/a+?/;
        console.log(pattern.exec(str));//["a", index: 0, input: "aaab", groups: undefined]

    但是正则有一个原则,就是去找第一个可能匹配的字符

    而不是最合适的位置

        var str="aaab";
        var pattern=/a+?b/;//此处并不会匹配到ab
        console.log(pattern.exec(str));//["aaab", index: 0, input: "aaab", groups: undefined]

    如上,并不会匹配到ab,因为正则从0开始就匹配到了a,之后会一直沿着下去寻找b


    贪婪匹配与非贪婪匹配的应用

        var str="<td>第一格</td><td>第二格</td>";
        var pattern=/<td>.*</td>/;//贪婪模式,匹配两格
        console.log(pattern.exec(str));//["<td>第一格</td><td>第二格</td>", index: 0, input: "<td>第一格</td><td>第二格</td>", groups: undefined]
    
        var pattern2=/<td>.*?</td>/;//非贪婪模式,匹配一格
        console.log(pattern2.exec(str));//["<td>第一格</td>", index: 0, input: "<td>第一格</td><td>第二格</td>", groups: undefined]

    选择 | 

        var str="css js";
        var pattern=/js|html|css/;
        console.log(pattern.exec(str));//["css", index: 0, input: "css js", groups: undefined]

    选择最先匹配的,而不是最合适的

        var str="ab";
        var pattern=/a|ab/;//先尝试匹配a,匹配成功后,不再匹配ab
        console.log(pattern.exec(str));//["a", index: 0, input: "ab", groups: undefined]

    正则匹配上传图片的后缀名:一般图片的后缀名有gif,jpg,jpeg,png等,并且不区分大小写

    /.gif|.jpg|.jpeg|.png/i


    分组和引用 ()

        var str="abab";
        var pattern=/(ab)+/;//将ab看成一个整体
        console.log(pattern.exec(str));//(2) ["abab", "ab", index: 0, input: "abab", groups: undefined]

    返回的数组中,第一个元素是匹配到的结果,第二个元素是 () 中分组的元素

    ( )  捕获分组

    (?: )  不捕获分组

        var str="abcd";
        var pattern=/(abc)d/;//匹配到abcd,捕获到abc
        console.log(pattern.exec(str));//(2) ["abcd", "abc", index: 0, input: "abcd", groups: undefined]
    
    
        var str="abcd";
        var pattern=/(?:abc)d/;//匹配到abcd,没有捕获
        console.log(pattern.exec(str));//(2) ["abcd", index: 0, input: "abcd", groups: undefined]

    平行分组依次返回

        var str="abcd";
        var pattern=/(ab)(cd)/;//匹配到abcd,第一个分组ab,第二个分组cd
        console.log(pattern.exec(str));//["abcd", "ab", "cd", index: 0, input: "abcd", groups: undefined]

    嵌套分组,按左边括号的顺序来进行返回

        var str="abcd";
        var pattern=/(a(b(c(d))))/;
        console.log(pattern.exec(str));//(5) ["abcd", "abcd", "bcd", "cd", "d", index: 0, input: "abcd", groups: undefined]

    可以在正则中直接使用分组  代表第n个分组

        var str="abcdab";
        var pattern=/(ab)cd1/;//1代表第一个分组,即ab
        console.log(pattern.exec(str));//(2) ["abcdab", "ab", index: 0, input: "abcdab", groups: undefined]

    分组的实际应用

    匹配外层容器中的html文本,外层容器是不确定的标签

        var str="<div><p>这是html文本</p></div>";
        var pattern=/<([a-zA-Z]+)>(.*?)</1>/;//1代表闭合标签,必须与开始标签相同
        console.log(pattern.exec(str));//["<div><p>这是html文本</p></div>", "div", "<p>这是html文本</p>", index: 0, input: "<div><p>这是html文本</p></div>", groups: undefined]

    如上,第一个分组是外层标签名,第二个分组是获取到的内层html

    .exec 返回的数组:

    匹配到的结果

    分组依次返回

    index 匹配到的位置索引

    input 被匹配的字符串


    位置匹配之首尾匹配

    ^ 字符串的开始

    $ 字符串的结束

        var str="js";
        var pattern=/^js/;
        console.log(pattern.exec(str));//["js", index: 0, input: "js", groups: undefined]
    
        var str="html js";
        var pattern=/^js/;
        console.log(pattern.exec(str));//null

    匹配全是数字

        var str="123mm567";
        var pattern=/^d+$/;
        console.log(pattern.exec(str));//null
    
        if(pattern.test(str)){
            alert("全是数字");
        }else{
            alert("不全是数字");//不全是数字
        }

    反向思考,匹配不是数字

        var str="123mm567";
        var pattern=/D/;
        console.log(pattern.exec(str));//["m", index: 3, input: "123mm567", groups: undefined]
    
        if(!pattern.test(str)){
            alert("全是数字");
        }else{
            alert("不全是数字");//不全是数字
        }

    位置匹配之单词边界匹配

    单词边界 

    非单词边界 B

        var str="js html";
        var pattern=/js/;
        console.log(pattern.exec(str));//["js", index: 0, input: "js html", groups: undefined]
    
        var str="@@@js@@@";//@也属于单词边界
        var pattern=/js/;
        console.log(pattern.exec(str));//["js", index: 0, input: "js html", groups: undefined]

    实现可兼容IE低版本的 getElementsByClassName()

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <ul>
            <li class="odd1 odd odd2">1</li>
            <li class="even">2</li>
            <li class="odd">3</li>
            <li class="even">4</li>
        </ul>
    <script>
        function getByClass(className,node){
            //高版本浏览器
            if(document.getElementsByClassName(className)){
                return document.getElementsByClassName(className)
            }else{
                //IE低版本浏览器
                var node=node || document;
                var arr=[];
                var elements=node.getElementsByTagName("*");//获取所有元素
                //注意,使用构造函数创建正则,其中的转义字符需要进行双重转义
                var pattern=new RegExp("(^|\s+)"+className+"($|\s+)");
                for(var i=0;i<elements.length;i++){
                    //匹配className
                    if(pattern.test(elements[i].className)){
                        arr.push(elements[i]);
                    }
                }
                return arr;
            }
        }
        var odds=getByClass("odd");
        for(var i=0;i<odds.length;i++){
            odds[i].style.background="pink";
        }
        var evens=getByClass("even");
        for(var i=0;i<evens.length;i++){
            evens[i].style.background="#abcdef";
        }
    </script> 
    </body>
    </html>

     使用单词边界的思路也可实现 

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <ul>
            <li class="odd1 odd odd2">1</li>
            <li class="even">2</li>
            <li class="odd">3</li>
            <li class="even">4</li>
        </ul>
    <script>
        function getByClass(className,node){
            //高版本浏览器
            if(document.getElementsByClassName(className)){
                return document.getElementsByClassName(className)
            }else{
                //IE低版本浏览器
                var node=node || document;
                var arr=[];
                var elements=node.getElementsByTagName("*");//获取所有元素
                //注意,使用构造函数创建正则,其中的转义字符需要进行双重转义
                var pattern=new RegExp("\b"+className+"\b");
                for(var i=0;i<elements.length;i++){
                    //匹配className
                    if(pattern.test(elements[i].className)){
                        arr.push(elements[i]);
                    }
                }
                return arr;
            }
        }
        var odds=getByClass("odd");
        for(var i=0;i<odds.length;i++){
            odds[i].style.background="pink";
        }
        var evens=getByClass("even");
        for(var i=0;i<evens.length;i++){
            evens[i].style.background="#abcdef";
        }
    </script> 
    </body>
    </html>

    前瞻性匹配 (?= )

    var str="javascript";
    var pattern=/java(?=script)/;//如果java后面跟的是script,那么匹配出java
    console.log(pattern.test(str));//true
    
    var str="java";
    var pattern=/java(?=script)/;//如果java后面跟的是script,那么匹配出java
    console.log(pattern.test(str));//false

    负前瞻性匹配 (?!)

    var str="javascript";
    var pattern=/java(?!script)/;//如果java后面跟的是script,那么不匹配出java
    console.log(pattern.test(str));//false
    
    var str="java";
    var pattern=/java(?!script)/;//如果java后面跟的不是script,那么匹配出java
    console.log(pattern.test(str));//true

    RegExp 对象的实例方法

    其中的转义字符需要进行双重转义

    var pattern=new RegExp("");
    console.log(pattern);//  //
    
    var pattern=new RegExp("\b");
    console.log(pattern);//  //

    因此,如果是 ,直面量方式转义为 \,构造函数双重转义为 \\

    var pattern=new RegExp("\\");
    console.log(pattern);//  /\/

    pattern 就是正则实例的对象,pattern 拥有的方法就是实例方法

    如:  .test()     .exec()

    var str="js js js";
    
    var pattern=/js/;
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 
    
    var pattern=/js/g;
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// ["js", index: 3, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// ["js", index: 4, input: "js js js", groups: undefined] 
    console.log(pattern.exec(str));// null
    console.log(pattern.exec(str));// ["js", index: 0, input: "js js js", groups: undefined] 

    如上,exec 有一个属性,叫 lastIndex,默认是0

    如果设置为全局匹配,则 lastIndex 是上一次匹配的结束位置的下一位

    如果匹配到为 null,就会自动重置为0,再次进行下一轮

    分组之后也能捕获

    var str="js js js";
    
    var pattern=/(j)s/;
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
    
    var pattern=/(j)s/g;
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// (2) ["js", "j", index: 3, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// (2) ["js", "j", index: 6, input: "js js js", groups: undefined]
    console.log(pattern.exec(str));// null
    console.log(pattern.exec(str));// (2) ["js", "j", index: 0, input: "js js js", groups: undefined]

    实例:

    var str="1.js 2.js 3.js";
    var pattern=/js/g;
    var total=0;//出现的总次数
    var result;
    
    while((result=pattern.exec(str))!=null){//先赋值再进行判断
        total++;
        console.log(result[0]+"第"+total+"次出现的位置是:"+result.index);
    }
    console.log("总共出现了"+total+"次");

    test 与 exec 类似原理

    var str="js js js";
    var pattern=/js/;
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//true
    
    var pattern=/js/g;
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//true
    console.log(pattern.test(str));//false
    console.log(pattern.test(str));//true

    .toString()  转字符串

    .toLocaleString() 转本地字符串(仅限少数语言)

    .valueOf() 返回正则本身

    var pattern=new RegExp("a\nb");
    console.log(pattern.toString());
    //  /a
    b/  此处返回的是字面量形式的字符串
    console.log(pattern.toLocaleString());//  /a
    b/
    console.log(pattern.valueOf());// /a
    b/
    console.log(pattern.valueOf()===pattern);// true

    实例属性

    .ignoreCase  判断是否忽略大小写

    .global  是否全局

    .multiline  是否匹配到多行

    .source 返回字面量正则本身

    var str="js js js";
    var pattern=/js/im;
    console.log(pattern.ignoreCase);//true
    console.log(pattern.global);//false
    console.log(pattern.multiline);//true
    console.log(pattern.source);//js
    console.log(pattern.source===pattern);//false

    .lastIndex 最后一次匹配的位置的后一位

    var str="js js";
    var pattern=/js/;
    console.log(pattern.lastIndex);//0
    pattern.test(str);
    console.log(pattern.lastIndex);//0
    pattern.test(str);
    console.log(pattern.lastIndex);//0
    pattern.test(str);
    console.log(pattern.lastIndex);//0
    pattern.test(str);
    console.log(pattern.lastIndex);//0
    
    var pattern=/js/g;
    console.log(pattern.lastIndex);//0
    pattern.test(str);
    console.log(pattern.lastIndex);//2
    pattern.test(str);
    console.log(pattern.lastIndex);//5
    pattern.test(str);
    console.log(pattern.lastIndex);//0 匹配不到时重置到0
    pattern.test(str);
    console.log(pattern.lastIndex);//2

    构造函数属性  RegExp.

    .input 待匹配的字符串  =  $_

    .lastMatch  最近一次匹配到的字符  =  $&

    .leftContext 最近一次匹配时左边的字符  = $`

    .rightContext 最近一次匹配时右边的字符  = $'

    .lastParen  最近一次匹配到的子选项(分组中的内容) = $+

    .$n  捕获分组

    var str="js js";
    var pattern=/(j)s/;
    pattern.exec(str);
    
    //待匹配的字符串
    console.log(RegExp.input);//js js
    console.log(RegExp["$_"]);//js js
    
    //最近一次匹配到的字符
    console.log(RegExp.lastMatch);//js
    console.log(RegExp["$&"]);//js
    
    //最近一次匹配时左边的字符
    console.log(RegExp.leftContext);//
    console.log(RegExp["$`"]);//
    
    //最近一次匹配时右边的字符
    console.log(RegExp.rightContext);// js
    console.log(RegExp["$'"]);// js
    
    //最近一次匹配到的子选项(分组中的内容)
    console.log(RegExp.lastParen);// j
    console.log(RegExp["$+"]);// j
    
    //捕获分组
    console.log(RegExp.$1);// j

    string 对象中,与正则相关的方法

    str.search()  与是否全局无关,只查找一个,如果有,就返回 index

    如果没有,就返回 -1

    var str="js js";
    var pattern=/(j)s/;
    console.log(str.search(pattern));//0
    var pattern=/aa/;
    console.log(str.search(pattern));//-1

    str.match()

    普通匹配时与 exec 相同

    全局匹配时:直接返回所有匹配的元素,分组会失效

    var str="js js";
    var pattern=/(j)s/;
    console.log(str.match(pattern));//(2) ["js", "j", index: 0, input: "js js", groups: undefined]
    var pattern=/aa/;
    console.log(str.match(pattern));//null
    
    var pattern=/(j)s/g;
    console.log(str.match(pattern));//(2) ["js", "js"]
    var pattern=/aa/;
    console.log(str.match(pattern));//null

    str.match( pattern )  

    非全局匹配时才能返回分组中的内容

    全局匹配时会返回所有匹配到的字符


    m 和 g 组合,结合首尾匹配,体现

    var str="1.js
    2.js
    3.js";
    var pattern=/js$/g;//匹配行尾的js,默认是一行
    console.log(str.match(pattern));//["js"]
    
    var pattern=/js$/mg;//匹配行尾的js,默认是多行
    console.log(str.match(pattern));//(3) ["js", "js", "js"]

    str.split()  字符串分割,转为数组

    var str="1,2,3";
    console.log(str.split(","));//(3) ["1", "2", "3"]
    
    var str="1,  2  , 3";
    var pattern=/s*,s*/g;
    console.log(str.split(pattern));//(3) ["1", "2", "3"]

    str.replace()  

    var str="i love js js";
    console.log(str.replace("js","html"));//i love html js
    
    var pattern=/js/g;
    console.log(str.replace(pattern,"html"));//i love html html

    replace 替换时间格式

    var str="2020-2-15";
    var pattern=/-/g;
    console.log(str.replace(pattern,"/"));//2020/2/15

    使用 $n 进行分组引用

    var str="i love pink";
    var pattern=/(pink)/g;
    document.write(str.replace(pattern,"<span style='background:pink'>$1</span>"));

     敏感词的过滤

    var str="中国军队和阿扁一起办证";
    var pattern=/国军|阿扁|办证/g;
    document.write(str.replace(pattern,"*"));//中*队和*一起*

    一个文字对应一个 * 号

    $0 是每次匹配到的内容

    var str="中国军队和阿扁一起办证";
    var pattern=/国军|阿扁|办证/g;
    document.write(str.replace(pattern,function($0){
        console.log($0);
        var result="";
        for(var i=0;i<$0.length;i++){
            result+="*";
        }
        return result;
    }));//中**队和**一起**

     f5  浅刷新

    ctrl+f5  深度刷新


    常用的正则表达式:

    1、QQ号:

    全数字 首位不是0  最少5位  (目前最多11位,以后可能会扩增)

    /^[1-9]d{4,10}$/
    /^[1-9]d{4,}$/

    2、用户名、昵称

    2-18位  中英文数字及下划线组成

    /^[ue400-u9fa5w]{2,18}$/
    /^[ue400-u9fa5a-zA-Z0-9_]{2,18}$/

    3、密码

    6-16位  不能有空白符  区分大小写

    /^S{6,16}$/

    4、去除字符串首尾的空白字符

    首先是去除首部或者尾部

    var str=" cyy ";
    console.log("|"+str+"|");// | cyy |
    
    var pattern=/^s+/;
    str=str.replace(pattern,"");//替换左边空白符
    
    var pattern2=/s+$/;
    /*
    这里使用 s+ 比使用 s* 效率高
    s* 无论如何都会进行替换,哪怕没有空白符
    s+ 只在有空白符的时候进行替换,否则直接返回
     */
    str=str.replace(pattern2,"");//替换右边空白符
    
    console.log("|"+str+"|");// |cyy|

    同时去除首尾空白符

    var str=" cyy ";
    console.log("|"+str+"|");// | cyy |
    
    var pattern=/^s+|s+$/g;
    str=str.replace(pattern,"");//替换左右空白符
    console.log("|"+str+"|");// |cyy|
    var str=" cyy ";
    console.log("|"+str+"|");// | cyy |
    
    function trim(str){
        return str.replace(/^s+/,"").replace(/s+$/,"");
    }
    console.log("|"+trim(str)+"|");// |cyy|

    5、转驼峰

    str.replace(pattern, 要替换的内容) 第二个参数可以是一个匿名函数的返回值

    匿名函数的参数中,第一个参数是匹配的内容,第二个参数开始是分组捕获的内容

    var str="background-color";
    var pattern=/-([a-z])/gi;//  此处匹配到-c
    
    //因为在匹配的结果中,第一个参数是匹配的内容,第二个参数开始是分组的内容
    //因此此处all为 -c   letter为 c
    //也可以用$0 $1表示
    console.log(str.replace(pattern,function(all,letter){
        return letter.toUpperCase();
    }));// backgroundColor
    console.log(str.replace(pattern,function($0,$1){
        return $1.toUpperCase();
    }));// backgroundColor
    
    // 封装转驼峰函数
    function toCamelCase(str){
        return str.replace(pattern,function($0,$1){
            return $1.toUpperCase();
        });
    }
    console.log(toCamelCase(str));//backgroundColor

    6、匹配HTML标签

    匹配开始标签和结束标签,标签中的内容不要

    var str="<p style='color:red' class='active'>这是段落</p>";
    var pattern=/<.+?>/g;//非贪婪模式匹配两个尖括号之间的内容
    console.log(str.match(pattern));
    
    var pattern=/<[^>]+>/g;//两个尖括号内部,没有匹配到结束的尖括号
    console.log(str.match(pattern));

    7、email 邮箱

    cyy@qq.com.cn

    cyy_1@qq.com

    cyy.com@qq.com.cn

    /^(w+.)*w+@(w+.)+[a-z]$/i

    8、URL

    /*
    http://www.baicu.com
    http或者https 可有可无
    除了 : 和 / ,其他的都属于主机名
    */ 
    
    //简化版,要求不高
    /^(https?://)?[^:/]+(:d+)?(/.*)?$/  
    
    //精确版
    //协议: http://  https://   ftp://  mailto://   file:///
    
    //匹配主机名 www.baidu.com
    //可以有连字符,但是连字符不能作为开头和结尾
    /^([a-z0-9]+.|[a-z0-9]+-[a-z0-9]+.)*[a-z]+$/i

    可以把经常用的正则存到一个对象中,如:

    var regExp={
        "chinese":/[u4e00-u9fa5]/,
        "qq":/^[1-9]d{4,}$/,
        ...
    }

    制作一个简易的正则测试工具

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            *{
                margin:0;
                padding:0;
            }
            body{
                background:#abcdef;
            }
            .wrap{
                width:1000px;            
                margin:10px auto;
                font-size:14px;
            }
            .container{
                width:650px;
                float:left;
            }
            .wrap h1{
                text-align: center;
                font-size:20px;
            }
            .textBox{
                border:1px solid #fff;
                padding:5px;
                width:638px;
                height:130px;
                border-radius:5px;
                resize:none;/*不允许拖拽输入框*/
                margin-top:15px;
            }
            div.textBox{
                background:#eee;
            }
            .pattenInput{
                width:180px;
                padding:5px;
                border:1px solid #fff;
                border-radius:5px;
            }
            .matchBtn{
                width:100px;
                text-align: center;
                padding:5px;
                background-color: pink;
                border:none;
                border-radius:5px;
                margin-left:10px;
            }
            #matchResult span,
            #replaceResult span{
                background:orange;
            }
            .list{
                width:280px;
                float:right;
                border:1px solid #fff;
                border-radius:5px;
                background-color: #fff;
                margin-top:14px;
                padding:20px;
            }
            .list dt{
                font-weight:bold;
                font-size:18px;
                margin-bottom:10px;
                color:#333;
            }
            .list dd{
                height:40px;
                line-height:40px;
            }
            .list dd a{
                display: block;
                text-decoration: none;
                color:#333;
            }
            .list dd a:hover{
                color:orange;
            }
            .footer{
                text-align: center;
            }
            .footer{
                zoom:1;
            }
            .wrap::after{
                content:"";
                display: block;
                clear:both;
            }
            .footer span{
                color:orange;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            <h1>正则表达式测试工具</h1>
            <div class="container">
                <textarea id="userInput" class="textBox" placeholder="请输入需要匹配的文本"></textarea>
                <p>
                    正则表达式:<input type="text" placeholder="请输入正则表达式" class="pattenInput" id="pattenInput">
                    <input type="checkbox" name="modifier" value="i">忽略大小写
                    <input type="checkbox" name="modifier" value="g">全局匹配
                    <input type="checkbox" name="modifier" value="m">多行匹配
                    <input type="button" value="测试匹配" id="matchBtn" class="matchBtn">
                </p>
                匹配结果:
                <!-- 原来使用textarea,内部文本不允许加标签,因此换为div -->
                <div id="matchResult" class="textBox" placeholder="请输入需要匹配的文本"></div>
                <p>
                    替换文本:<input type="text" placeholder="请输入替换文本" class="pattenInput" id="replaceInput">
                    <input type="button" value="正则替换" id="replaceBtn" class="matchBtn">
                </p>
                替换结果:
                <!-- 原来使用textarea,内部文本不允许加标签,因此换为div -->
                <div id="replaceResult" class="textBox" placeholder="请输入需要匹配的文本"></div>
            </div>
            <dl class="list" id="list">
                <dt>常用正则表达式</dt>
                <dd><a href="javascript:void(0)" title="[u4e00-u9fa5]">匹配中文字符</a></dd>
                <dd><a href="javascript:void(0)" title="[1-9]d{4,}">QQ</a></dd>
            </dl>
        </div>
        <p class="footer">本程序由<span>cyy</span>制作,欢迎大家使用~</p>
    
    <script>
        var userInput=document.getElementById("userInput");
        var pattenInput=document.getElementById("pattenInput");
        var modifiers=document.getElementsByName("modifier");
        var matchBtn=document.getElementById("matchBtn");
        var matchResult=document.getElementById("matchResult");
    
        var replaceInput=document.getElementById("replaceInput");
        var replaceBtn=document.getElementById("replaceBtn");
        var replaceResult=document.getElementById("replaceResult");
    
        var links=document.getElementById("list").getElementsByTagName("a");
    
        var pattern="";
        var modifier="";
    
        //处理模式修饰符
        for(var i=0;i<modifiers.length;i++){
            modifiers[i].onclick=function(){
                modifier="";//每次点击后先清空原来的
                for(var j=0;j<modifiers.length;j++){
                    if(modifiers[j].checked){
                        modifier+=modifiers[j].value;
                    }
                }
            }
        }
    
        //点击按钮进行匹配
        matchBtn.onclick=function(){
            //没有输入文本
            if(!userInput.value){
                alert("请输入待匹配的文本~");
                userInput.focus();//获取光标
                return;//不再执行下面的脚本
            }
    
            //没有输入正则
            if(!pattenInput.value){
                alert("请输入待匹配的文本~");
                pattenInput.focus();
                return;
            }
    
            pattern=new RegExp("("+pattenInput.value+")",modifier);
            console.log(userInput);
            matchResult.innerHTML=pattern.exec(userInput.value) ? userInput.value.replace(pattern,"<span>$1</span>"): "(没有匹配到哦~)";
        }
    
        //点击按钮进行替换
        replaceBtn.onclick=function(){
            //没有输入文本
            if(!userInput.value){
                alert("请输入待匹配的文本~");
                userInput.focus();//获取光标
                return;//不再执行下面的脚本
            }
    
            //没有输入正则
            if(!pattenInput.value){
                alert("请输入待匹配的文本~");
                pattenInput.focus();
                return;
            }
    
            //没有输入替换文本
            if(!replaceInput.value){
                alert("请输入要替换的文本~");
                replaceInput.focus();
                return;
            }
    
            pattern=new RegExp("("+pattenInput.value+")",modifier);
            replaceResult.innerHTML=userInput.value.replace(pattern,"<span>"+replaceInput.value+"</span>");
        }
    
        //点击右侧快捷正则
        for(var i=0;i<links.length;i++){
            links[i].onclick=function(){
                pattenInput.value=this.title;//this指当前点击的元素
            }
        }
    
    
    
    </script>
    </body>
    </html>

     补充:

    () 分组可以捕获内容

    (?:) 不参与捕获

    $1  $2... 分别表示捕获到的内容

    如何获取捕获到的内容:

    exec() 返回的数组中,第一个是匹配到的内容,第二个开始是捕获的内容

    /1/ 模式中,直接在正则中引用捕获到的内容

    replace() 的第2个参数中,$1 (如果第2个参数是匿名函数,这个匿名函数的第一个参数是匹配到的内容,第二个参数开始是捕获到的内容)

    RegExp.$1

  • 相关阅读:
    CVE-2019-16278:Nostromo Web服务器的远程命令执行
    内网渗透一(信息收集)
    Apache Flink 任意jar包上传漏洞
    Apache ---- Solrl漏洞复现
    linux内核过高导致vm打开出错修复脚本
    lvm拓展
    文件时间进度扫描控制,可回溯,空闲扫描,系统时间调整不影响
    Raid 管理
    curl 工具使用
    docker 入门
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12313738.html
Copyright © 2011-2022 走看看