关于正则

作者: 饥人谷_楠柒 | 来源:发表于2016-12-22 02:50 被阅读248次

    概念:

    正则表达式(Regular Expression)是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

    通俗来讲:正则表达式是用来处理字符串的,可以用一些特定字符来描述字符串里字符出现的规则,从而匹配,提取或者替换符合某一个规则的字符串。比如(像文章关键字替换,密码,手机等认证,邮箱等,都要用到正则)

    创建:

    • 第一种:构造函数
      var reg = new RegExp('hi','g')
    • 第二种:字面量
      var reg = /hi/g

    修饰符:

    1.g:global,全文搜索,不添加的话搜索到第一个结果停止搜索
    2.i:ingore case,忽略大小写,默认大小写敏感
    3.m:multiple lines,多行搜索
    下面列子理解下g,i,m的作用; 
    
    QQ截图20161221221757.jpg QQ截图20161221224544.jpg

    正则常用的两种方法:

    test方法:test() 方法检索字符串中的指定值。返回值是 true 或 false。

    var str = "my name is zyn"
    var reg = /name/
    console.log(reg.test(str); //ture
    

    exec方法:exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。

    var str = "my name is zyn"
    var reg = /name/
    console.log(reg.exec(str); //name
    

    字符类

    我们可以使用元字符[]来构建一个简单的类,所谓类是指,符合某些特征的对象,是一个泛指,而不是特指某个字符了,我们可以使用表达式 [abc]把字符a或b或c归为一类,表达式可以匹配这类的字符(如)
    
    var str = "abcdefacbsq";
    var reg =/[abc]/g;
    console.log(str.match(reg));//["a", "b", "c", "a", "c", "b"]
    
    var reg1 =/[a-e]/g;
    console.log(str.match(reg1));//["a", "b", "c", "d", "e", "a", "c", "b"]
    

    取反

    元字符[]组合可以创建一个类,我们还可以使用元字符^创建反向类/负向类,反向类的意思是不属于XXX类的内容,表达式 [^abc] 表示不是字符a或b或c的内容(如)
    
    var str = "abcdefacbsq";
    var reg =/[^abc]/g;
    console.log(str.match(reg));//["d", "e", "f", "s", "q"]
    
    var reg1 =/[^a-e]/g;
    console.log(str.match(reg1));//["f", "s", "q"]
    

    元字符

    正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符
    如(( [ { \ ^ $ | ) ? * + .)后面会讲到
    

    并不是每个元字符都有特定的意义,在不同的组合中元字符有不同的意义,分类看一下

    字符 含义
    \t 水平制表符
    \r 回车符
    \n 换行符
    \f 换页符
    \cX 与X对应的控制字符Ctrl+X
    \v 垂直制表符
    \0 空字符

    预定义类

    字符 字符 含义
    . [^\r\n] 除了回车符和换行符之外的所有字符
    \d [0-9] 数字字符
    \D [^0-9] 非数字字符
    \s [\t\n\x0B\f\r] 空白符
    \S [^\t\n\x0B\f\r] 非空白符
    \w [a-zA-Z_0-9] 单词字符,字母,数字下划线
    \W [^a-zA-Z_0-9] 非单词字符

    边界

    字符 含义
    ^ 以xxx开头
    $ 以xxx结尾
    \b 单词边界
    \B 非单词边界

    量词

    字符 含义
    出现零次或一次(最多出现一次)
    + 出现一次或多次(至少出现一次)
    * 出现零次或多次(任意次)
    {n} 出现n次
    {n,m} 出现n到m次
    {n,} 至少出现n次
    {,m} 最多出现m次

    贪婪模式与非贪婪模式

    贪婪模式:量词在默认下是尽可能多的匹配的;
    非贪婪模式:让正则表达式尽可能少的匹配,也就是说一旦成功匹配不再继续尝试,做法很简单,在量词后加上?
    简单来说JS中的正则表达式的贪婪模式和非贪婪模式主要是匹配方式上有所不同(如)
    
    var  str = "how  ! old are  you! I am !30! year"
    var reg =/!.+!/
    console.log(str.match(reg) );//["! old are  you! I am !30!"]
    我们想要的是["! old are you!",!30!]可是为什么得到这个结果?
    这是正则表达式的匹配方式导致的。
    正则表达式默认的匹配的方式就是贪婪模式。
    
    • 贪婪模式:

    1 首先在"how ! old are you! I am !30! year"
    这个字符串中,使用/!.+!/进行匹配,那么这个正则式首先寻找的是一个感叹号! 如下图:

    QQ截图20161222001216.jpg

    2 于是/!.+!/正则就会开始匹配.,而 . 这个符号可以匹配除换行符外的全部字符,于是它就一直匹配到了最后,直到文本结束:

    QQ截图20161222001330.jpg

    3 .号匹配完毕后,开始匹配后面的!,于是正则/!.+!/开始往回匹配感叹号!,一直匹配到30后面的!,发现符合规则了,于是匹配出来的就是这一串字符串

    QQ截图20161222001722.jpg
    所以会有以上的输出,那怎么得到我们要的结果呢?
    改为费贪婪模式:reg =/!.+?!/
    
    var  str = "how  ! old are  you! I am !30! year"
    var reg =/!.+?!/g
    console.log(str.match(reg) );//["! old are  you!", "!30!"]
    
    
    • 非贪婪模式:

    1 首先在"how ! old are you! I am !30! year"
    这个字符串中,使用/!.+!/进行匹配,那么这个正则式首先寻找的是一个感叹号! 如下图:

    QQ截图20161222001216.jpg

    2 然后进行 . 的匹配,但是与贪婪模式不同的是,它每匹配一次.
    ,就会往后匹配一次!,于是就出现了如下图的结果:

    QQ截图20161222002227.jpg

    3 因为g是全局匹配,所以该正则又会从头开始匹配第一个!,到了!30后,匹配成功第一个!和两个.,以及后面的!,于是!30!也被匹配上了,然后该正则又剩下的字符串开始从新匹配,而后面因为不能匹配出第一个!,于是就没有匹配出来:

    QQ截图20161222002554.jpg

    下面做一些练习题

    1. \d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^$分别是什么?

    \d:数字字符;
    \w:单词字符,字母,数字下划线;
    [a-zA-Z0-9]:取字母a到z任意字母的大小写,和任意数字0到9;
    \b:单词边界;
    .:除了回车符和换行符之外的所有字符;
    +:出现一次或者多次;
    ?:出现0次或者一次;
    x{3}:x出现3次;
    ^$:^:表示匹配任何开头为输出值的字符串,$:表示匹配任何结尾为输出值的字符串,两者结合就是一个空字符;
    

    2. 贪婪模式和非贪婪模式指什么?

    贪婪模式和非贪婪模式,或者说匹配优先和忽略优先。标准量词修饰的子表达式,在可匹配可不匹配的情况下,总会先尝试进行匹配,称贪婪模式,例如{n}、{m,n}、*、+、. 。
    而非贪婪模式就是在可匹配可不匹配的情况下,总会优先忽略匹配,直到必须匹配才能使表达式匹配成功时,才会进行匹配。只要在标准量词后加?即进入非贪婪模式。例如{n}?、*?、??、+?。
    

    3. 写一个函数trim(str),去除字符串两边的空白字符

    function trim(str){
        return str.replace(/(^\s+)|(\s+$)/g,"");    
    }
    console.log(trim('ab c'));//ab c
    console.log(trim('ab c '));//ab c
    console.log(trim(' ab c'));//ab c
    console.log(trim(' abc '));//abc
    console.log(trim('  abc   '));//abc
    console.log(trim(' a b c '));//a b c
    

    4. 使用实现 addClass(el, cls) hasClass(el, cls) removeClass(el,cls)使用正则

    var test = document.getElementById('test')
    function hasClass(el, cls) {
        //左边是开头或者空格,右边是结尾或者空格
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', 'g');
      // var reg = new RegExp('(\s|^)' + cls + '(\s|$)', 'g');
        return reg.test(el.className);
    }
    
    
    function addClass(el, cls) {
        var reg = new RegExp('(\\s|^)' + cls + '(\s|$)', 'g');
    
        if (!reg.test(el.className)) {
            el.className = el.className + ' ' + cls;
        }
    }
    
    function removeClass(el, cls) {
        var reg = new RegExp('(\\s|^)' + cls + '(\s|$)', 'g');
    
        //先替换成空格 再去掉多余的空格
        if (reg.test(el.className)) {
            el.className = el.className.replace(reg, ' ').replace(/\s{2,}/g, ' ');
        }
    }
    
    

    5. 写一个函数isEmail(str),判断用户输入的是不是邮箱

    function isEmail(str){
    
        var reg = /(\S)+[@]{1}(\S)+[.]{1}(\w)+/
        return reg.test(str);
    }
    
    

    6. 写一个函数isPhoneNum(str),判断用户输入的是不是手机号

    function isPhone(str){
    
        var reg = /^1[3-9]{10}$/;
        return reg.test(str);
    
    }
    

    7 .写一个函数isValidUsername(str),判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线)

    function isValidUsername(str){
    
        var reg = /\w{6,20}$/
        return reg.test(str)
    }
    

    8 .写一个函数isValidPassword(str),判断用户输入的是不是合法密码(长度6-20个字符,包括大写字母、小写字母、数字、下划线至少包括两种)

    
    function isValidPassword(str){
    
        if(str.length<6 || str.length>20){
    
            return false;
        }//长度条件
    
        if(/[^\w]/g.test(str))
        {
            return false;
        }//其他字符;
    
        if(/(^[a-z]+$)|(^[A-Z]+$)|(^\d+$)|(^_+$)/g.test(str)){
    
             return fasle;
        }//只有一种值得情况
        return true;
    
    }
    
    

    9. 写一个正则表达式,得到如下字符串里所有的颜色

    var re = /*正则...*/
    var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 "
    alert( subj.match(re) )
    
    var reg = /#[A-Fa-f0-9]+/g;
    var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 ";
    console.log(subj.match(reg));//["#121212", "#AA00ef", "#fddee", "#fd2"]
    
    

    10.下面代码输出什么? 为什么? 改写代码,让其输出hunger, world.

    var str = 'hello "hunger" , hello "world"';
    var pat = /".*"/g;str.match(pat);
     // 输出结果是:"hunger" , hello "world",原因是因为.*使这个正则表达式处于贪婪模式,所以在hunger前面有一个",而world的后面也有一个",并且中间的所有字符都可以匹配.这个符号,所以第一个双引号和最后一个双引号之间的字符全部都匹配上了;
    
    var str = 'hello  "hunger" , hello "world"';
    var pat =  /".*?"/g;
    console.log(str.match(pat));//[""hunger"", ""world""]
    //改写成了非贪婪模式;
    

    11.补全如下正则表达式,输出字符串中的注释内容. (可尝试使用贪婪模式和非贪婪模式两种方法)

    str = '.. <!-- My -- comment \n test --> .. <!----> .. '
    re = /.. your regexp ../str.match(re) // '<!-- My -- comment \n test -->', '<!---->'
    
    非贪婪模式
    
    str = '.. <!-- My -- comment \n test --> ..  <!----> .. '
    re = /<!--[\w\W]*?-->/g;
    
    console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
    
    
    str = '.. <!-- My -- comment \n test --> ..  <!----> .. ';
    re = /<[^\r]*?>/g;
    console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
    
    贪婪模式
    str = '.. <!-- My -- comment \n test --> ..  <!----> .. '
    re = /<!--[^>]*-->/g;
    console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
    
    
    str = '.. <!-- My -- comment \n test --> ..  <!----> .. ';
    re = /[^.]*>/g;
    console.log(str.match(re)); // '<!-- My -- comment \n test -->', '<!---->'
    
    

    12. 补全如下正则表达式

    var re = /* your regexp */
    var str = '<> <a href="/"> <input type="radio" checked> <b>'
    str.match(re) // '<a href="/">', '<input type="radio" checked>', '<b>'
    
    var re = /<[a-z].*?>/g
    var str = '<> <a href="/"> <input type="radio" checked> <b>'
    console.log(str.match(re))
    //["<a href="/">", "<input type="radio" checked>", "<b>"]
    //非贪婪模式
    
    
    var re = /<[^>]+>/g;
    var str = '<> <a href="/"> <input type="radio" checked> <b>';
    console.log(str.match(re));
     // '<a href="/">', '<input type="radio" checked>', '<b>'
    //贪婪模式
    
    

    版权归饥人谷--楠柒所有 如有转载请标明出处

    相关文章

      网友评论

      本文标题:关于正则

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