• 正则的查缺补漏


    多选分支|

    var regex = /good|goodbye/g;
    var string = "goodbye";
    console.log( string.match(regex) ); 
    // => ["good"]
    也就是说分支也是惰性的,当前匹配上了,后面的不再尝试了
    var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
    var string = "#ffbbad #Fc01DF #FFF #ffE";
    console.log( string.match(regex) ); 
    // => ["#ffbbad", "#Fc01DF", "#FFF", "#ffE"]
    //所以应该把{6} 写前面  匹配少到匹配多
    

    (?=p) 和(?!p) 零宽断言

    零宽断言:零宽度的匹配,匹配到的内容不保存在匹配结果中,最终匹配的结果只是一个位置。

    Javascript 只支持零度先行断言
    ?=p         表示p前面的位置 (理解^)     先行断言
    ?!p         表示?=p的反面意思    负向先行断言
    零宽断言返回的是位置而不是字符
        console.log("abcdefg".match(/ab(?=cd)/g));
        console.log("abcdefg".match(/(?=cd)efg/g));//没匹配上返回null
        console.log("abcdefg".match(/ab(?=cd)cdefg/g));
    var result = "hello".replace(/(?!l)/g, '#');
    console.log(result); 
    // => "#h#ell#o#"    
    找到所有的.min.css文件的文件名
    let str = "a.min.css;.min.css;.css;min.css;b.css;c.min.js;d.css;e.a.min.css";
    console.log(str.match(/w+(?=.min.css)/g));
    
    测试一个文件是否是.css后缀,但是不能用.min.css
    var reg=/^(?!.*.min.css$).+.css$/;
    
    reg.test('a.min.css'); // false
    reg.test('.min.css'); // false
    reg.test('.css'); // false
    reg.test('min.css'); // true
    reg.test('b.css'); // true
    reg.test('c.mining.css'); // true
    
    数字的千位分隔符
    '12345678'.replace(/B(?=(d{3})+)/g,',')
    
    (?=.*[0-9])
    翻译 :  有多个任意字符后面必须包含个数字(至少包含)
    
    (?!^[0-9]{6,12}$)
    翻译:  不能全部是数字(不能全部)
    

    w

    单词w  [0-9a-zA-Z_]
      单词边界
    

    分组

    ()
    match [i]  查看每一个组的数值
    $1  $2   $3  记得加引号包起来
    构造函数的全局属性$1至$9来获取
    
    var regex = /(d{4})-(d{2})-(d{2})/;
    var string = "2017-06-12";
    console.log(string.replace(regex, "$1 / $2 / $3"));  
    

    非捕获分组

    (?:p)
    var regex = /(?:ab)+/g;
    var string = "ababa abbb ababab";
    console.log( string.match(regex) ); 
    // => ["abab", "ab", "ababab"]
    
    var data = 'windows 98 is ok';
    data.match(/windows (?:d+)/);  // ["windows 98"]
    data.match(/windows (d+)/);    // ["windows 98", "98"]
    它跟() 不同的地方在于,不作为子匹配返回
    
    找到每个单词的首字母
    'my name is epeli'.replace(/(?:^|s)w/g, c => c.toUpperCase())
    

    反向引用

    1, 2 ,3  ...
    /([a-z]d)-d(123)1/
    指的是每一组小括号就是所谓的一组   1 就是 [a-z]d  第一个分组的匹配
    当我们不需要使用分组引用和反向引用时,此时可以使用非捕获分组
    /^[+-]?(d+.d+|d+|.d+)$/
    
    可以修改成:
    
    /^[+-]?(?:d+.d+|d+|.d+)$/
    

    位置字符和字符序列优先级要比竖杠高

    ^(abc|bcd)$  要用括号包起来
    ^([abc]{3})+$
    

    字符组中的元字符

    var string = "^$.*+?|\/[]{}=!:-,";
    var regex = /[^$.*+?|\/[]{}=!:-,]/g;
    console.log(string.match(regex));
    其中[]	^	-  需要转义
    竖杠的优先级最低,即最后运算。
    另外关于元字符转义问题,当自己不确定与否时,尽管去转义,总之是不会错的。
    

    优化

    独立出确定字符
    	/a+/ 可以修改成 /aa*/
    提取公共部分
        比如/^abc|^def/,修改成/^(?:abc|def)/。
    
        又比如/this|that/,修改成/th(?:is|at)/。
     减少分支的数量,缩小它们的范围
     	/red|read/,可以修改成/rea?d/。此时分支和量词产生的回溯的成本是不一样的。但这样优化后,可读性会降低的。
    

    正则表达式的四种操作

    正则表达式是匹配模式

    正则  gi   g全局i区分大小写 m多行匹配
    exec
    注意分组的参数
    若检索成功,返回匹配的数组,否则返回null
    let result = /len/g.exec('hello len!!');
    
    //[ 'len', index: 6, input: 'hello len!!' ]
    test
    test整体匹配时需要使用^和$
    若匹配成功返回true否则返回false
    let str = "hello leo!";
    let res = /leo/.test(str);   // true
    
    search
    若检索成功,返回第一个与正则对象匹配的字符串的起始位置,否则返回-1
    let str = "hello leo!";
    let res = str.search(/leo/g);  // 6
    
    match
    匹配记得加/g
    若检索成功,返回与reg匹配的所有结果的一个数组,否则返回null
    str.match(regSS)
    

    验证(最常用的是test )

    判断一个字符串中是否有数字
    使用 search
        ~~ 常用来取整,也可以用来转换成数字类型
        ~~true == 1
        ~~false == 0
        ~~"" == 0
        ~~[] == 0
        ~~undefined ==0
        ~~!undefined == 1
        ~~null == 0
        ~~!null == 1
        ~为取反运算符,如果names.indexOf(name)返回值为-1,即names不包含name,那么~-1 = 0。其他值取反后值都不为0。结合!~来判断names是否包含name
        
        
        var string = "abc123";
        console.log( !!~string.search(regex) );
        // => true
        
    使用testvar regex = /d/;
    
        var string = "abc123";
        console.log( regex.test(string) );
        // => true
    使用match
    
        var regex = /d/;
        var string = "abc123";
        console.log( !!string.match(regex) );
        // => true
        
    使用exec
        var regex = /d/;
        var string = "abc123";
        console.log( !!regex.exec(string) );
        // => true
    

    切分(在js中常用split)

    var regex = /,/;
    var string = "html,css,javascript";
    console.log( string.split(regex) );
    // => ["html", "css", "javascript"]
    
    var regex = /D/;
    console.log( "2017/06/26".split(regex) );
    console.log( "2017.06.26".split(regex) );
    console.log( "2017-06-26".split(regex) );
    // => ["2017", "06", "26"]
    // => ["2017", "06", "26"]
    // => ["2017", "06", "26"]
    

    提取(正则通常要使用分组引用(分组捕获)最常用的是match)

    match
    
        var regex = /^(d{4})D(d{2})D(d{2})$/;
        var string = "2017-06-26";
        console.log( string.match(regex) );
        // =>["2017-06-26", "2017", "06", "26", index: 0, input: "2017-06-26"]
        
    exec
    
        var regex = /^(d{4})D(d{2})D(d{2})$/;
        var string = "2017-06-26";
        console.log( regex.exec(string) );
        // =>["2017-06-26", "2017", "06", "26", index: 0, input: "2017-06-26"]
    test
        var regex = /^(d{4})D(d{2})D(d{2})$/;
        var string = "2017-06-26";
        regex.test(string);
        console.log( RegExp.$1, RegExp.$2, RegExp.$3 );
        // => "2017" "06" "26"
    search
        var regex = /^(d{4})D(d{2})D(d{2})$/;
        var string = "2017-06-26";
        string.search(regex);
        console.log( RegExp.$1, RegExp.$2, RegExp.$3 );
    	// => "2017" "06" "26"
    replace
        var regex = /^(d{4})D(d{2})D(d{2})$/;
        var string = "2017-06-26";
        var date = [];
        string.replace(regex, function(match, year, month, day) {
            date.push(year, month, day);
        });
        console.log(date);
        // => ["2017", "06", "26"]
    

    替换(replace)

    相关API(字符串四种支持正则)

    String#search
    
    String#split
    
    String#match
    
    String#replace
    
    RegExp#test
    
    RegExp#exec
    

    注意点

    match 返回结果的格式,与正则对象是否有修饰符g有关
    	没有g,返回的是标准匹配格式,数组的第一个元素是整体匹配的内容
    	有g,返回的所有匹配的内容
    	
    exec方法就能解决这个问题,它能接着上一次匹配后继续匹配
    正则实例lastIndex属性,表示下一次匹配开始的位置
    var string = "2017.06.27";
    var regex2 = /(d+)/g;
        console.log( regex2.exec(string) );
        console.log( regex2.lastIndex);
        console.log( regex2.exec(string) );
        console.log( regex2.lastIndex);
        console.log( regex2.exec(string) );
        console.log( regex2.lastIndex);
        console.log( regex2.exec(string) );
        console.log( regex2.lastIndex);
        // => ["2017", "2017", index: 0, input: "2017.06.27"]
        // => 4
        // => ["06", "06", index: 5, input: "2017.06.27"]
        // => 7
        // => ["27", "27", index: 8, input: "2017.06.27"]
        // => 10
        // => null
        // => 0
    从上述代码看出,在使用exec时,经常需要配合使用while循环    
    
    split
    它可以有两个参数,第二个参数表示数组的最大长度
    var string = "html,css,javascript";
    console.log( string.split(/,/, 2) );
    // =>["html", "css"]
    

    replace(很强大,单独拿出来)

    这是因为它的第二个参数,可以是字符串,也可以是函数。
    第二个参数是字符串时
        $1,$2,...,$99 匹配第1~99个分组里捕获的文本
        $& 匹配到的子串文本
        $` 匹配到的子串的左边文本 
        $' 匹配到的子串的右边文本
        $$ 美元符号
    例如,把"2,3,5",变成"5=2+3":
        var result = "2,3,5".replace(/(d+),(d+),(d+)/, "$3=$1+$2");
        console.log(result);
        // => "5=2+3"
    又例如,把"2,3,5",变成"222,333,555":
        var result = "2,3,5".replace(/(d+)/g, "$&$&$&");
        console.log(result);
        // => "222,333,555"
    再例如,把"2+3=5",变成"2+3=2+3=5=5":
        var result = "2+3=5".replace(/=/, "$&$`$&$'$&");
        console.log(result);
        // => "2+3=2+3=5=5"
    当第二个参数是函数时,我们需要注意该回调函数的参数具体是什么:
        "1234 2345 3456".replace(/(d)d{2}(d)/g, function(match, $1, $2, index, input) {
            console.log([match, $1, $2, index, input]);
        });
        // => ["1234", "1", "4", 0, "1234 2345 3456"]
        // => ["2345", "2", "5", 5, "1234 2345 3456"]
        // => ["3456", "3", "6", 10, "1234 2345 3456"]
    
  • 相关阅读:
    linux --- mysql --- max_allowed_packet
    idea 快捷键
    TypedArray和obtainStyledAttributes使用
    ubuntu中怎样添加或删除一个PPA源
    Ubuntu 14.04 用户安装 Cinnamon 2.2.0
    android-pulltorefresh源码解析(1)--PullToRefreshListView的使用
    Android菜单详解(四)——使用上下文菜单ContextMenu
    Android菜单详解(五)——使用XML生成菜单
    Android菜单详解(二)——创建并响应选项菜单
    Android菜单详解(三)——SubMenu和IconMenu
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/10259800.html
Copyright © 2020-2023  润新知