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

  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12313738.html
Copyright © 2011-2022 走看看