• Javascript正则表达式难点、重点


    重复的贪婪性

     {n,m}   {n,}   {n}   ?   +   *
    
    • ?表示匹配0次或1次,(最多匹配1次);
    • +表示匹配1次或多次,(最少匹配1次);
    • *表示匹配0次或多次,(匹配任意次);
    • {m,n}表示匹配m到n次,(最少m次,最多n次);

    举例:

    console.log("@123@456@789".match(/d{1,2}/g))
    // ==> ["12", "3", "45", "6", "78", "9"]
    

    {1,2}优先匹配2次(贪婪),还可以匹配1次,可以看到上面的结果为["12", "3", "45", "6", "78", "9"];

    非贪婪,在量词后面加一个?即可;

    console.log("@123@456@789".match(/d{1,2}?/g))
    // ==> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    

    表示匹配到1次了就不再匹配了(非贪婪)。

    分组

    假设有这样不同格式的日期(2016-10-15、2016/10/15、2016.10.15),如果想要提取具体的年月日,可以这么写:

    console.log("2016-10-15".match(/d{4}[/-.]d{2}[/-.]d{2}/))
    // ==> ["2016-10-15"]
    

    上面是没有添加分组时候的,此时,可以给它添加分组:

    console.log("2015-10-15".match(/(d{4})[/-.](d{2})[/-.](d{2})/))
    // ==> ["2016-10-15", "2016", "10", "15"]
    

    可以看到输出的结果是一个array,里面的年月日就已经被提取出来了。接下来再看:

    console.log("2015-10-15".replace(/(d{4})[/-.](d{2})[/-.](d{2})/g,"$3-$2-$1"))
    // ==> "15-10-2016"
    

    可以看到结果变成了:15-10-2016,这是因为表达式匹配的内容可以用$1,$2,...来表示:

    忽略分组(非捕获分组)

    var reg = /(?:d{4})(-|.|/)d{2}1d{2}/;
    console.log(reg.test('2016-10-15'));    // ==>true
    console.log(reg.test('2016.10.15'));    // ==>true
    console.log(reg.test('2016/10/15'));    // ==>true
    console.log(reg.test('2016-10/15'));    // ==>false
    

    再来一个例子:

    console.log("1-2-3-4".replace(/(d)/g,"x"));
    // ==> x-x-x-x
    console.log("1-2-3-4".replace(/(-d)/g,"x"));
    // ==> 1xxx
    console.log("1-2-3-4".replace(/-(d)/g,"x"));
    // ==> 1xxx
    console.log("1-2-3-4".replace(/(-d)/g,"0$1"));
    // ==> 10-20-30-4
    console.log("1-2-3-4".replace(/-(d)/g,"0$1"));
    // ==> 1020304
    console.log("1-2-3-4".match(/(-d)/g));
    // ==> ["-2", "-3", "-4"]
    console.log("1-2-3-4".match(/-(d)/g));
    // ==> ["-2", "-3", "-4"]
    console.log(RegExp.$1);
    // ==> 4
    

    再来个时间转化的例子:

    var date="2014-12-30 12:30:20";
    console.log(date.replace(/(d{4})-(d{2})-(d{2})/g,"$2-$3-$1"));
    // ==> "12-30-2014 12:30:20"
    console.log(date.replace(/(d{4})-(d{2})-(d{2})s[w+:]{8}/g,"$2-$3-$1"))
    // ==> "12-30-2014"
    

    向前查找 (此东西是个位置!)

    即(?=p)和(?!p)。其中p是一个子正则表达式。关于锚字符匹配的问题,在ES5中总共有6个。

    ^ $  B (?=p) (?!p)
    

    (?=3)表示啥意思呢?表示3前面的位置,见例子:

    console.log("a1b2c3d4".replace(/(?=3)/g,"x"));
    // ==> a1b2cx3d4
    console.log("a1b2c3d4".replace(/(?=d)/g,"x"));
    // ==> ax1bx2cx3dx4
    

    那么(?!...)的概念也好理解了,表示取非的,见例子:

    console.log("a1b2c3d4".replace(/(?!3)/g,"x"));
    // ==> xax1xbx2xc3xdx4x
    console.log("a1b2c3d4".replace(/(?!d)/g,"x"));
    // ==> xa1xb2xc3xd4x
    

    注意(?!d)表示的意思不是“非数字前面的位置”,而是所有位置中扣掉数字前面位置。

    再来看一个例子:

    假如"a1b2c3d4"这个字符串,我要匹配b或c前面的数字,怎么做呢?

    console.log("a1b2c3d4".replace(/d(?=[bc])/g,"x"));
    // ==> axbxc3d4
    console.log("a1b2c3d4".match(/d(?=[bc])/g));
    // ==> ["1", "2"]
    

    再来看一个:假如有这样一个字符串"a1a2a3a4a5",我要匹配所有的a但不包括3前面的a,怎么做呢?见下面:

    console.log("a1a2a3a4a5".replace(/a(?!3)/g,"x"));
    // ==> x1x2a3x4x5
    

    总结:

    • (?=X ) 零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,w+(?=d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
    • (?!X) 零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,w+(?!d) 与后不跟数字的单词匹配,而不与该数字匹配 。
    • (?<=X) 零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。
    • (?<!X) 零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配

    最后:来个小例子结束本篇文章:(利用正则来获取dom的class)

    <div class="box"></div>
    <script>
    	function getByClass(oParent, sClass) {
    		var tag = oParent.getElementsByTagName('*');
    		var arr = [];
    		var reg = new RegExp('\b' + sClass + '\b', "i");
    		for (var i = 0; i < tag.length; i++) {
    			if (reg.test(tag[i].className)) {
    				arr.push(tag[i]);
    			}
    		}
    		return arr;
    	}
    	function findClassInElements(className, type) {
    		var ele = document.getElementsByTagName(type || '*');
    		var result = [];
    		var reg = new RegExp('(^|\s)' + className + '(\s|$)');
    		for (var i = 0; i < ele.length; i++) {
    			if (reg.test(ele[i].className)) {
    				result.push(ele[i]);
    			}
    		}
    		return result
    	}
    	console.log(getByClass(document.body, "box"));
    	console.log(findClassInElements('box'));
    	var box = findClassInElements('box');
    
    	box.forEach(function(value,index){
    		console.log(value);
    	})
    </script>
    
  • 相关阅读:
    架构师养成记--34.Redis持久化
    架构师养成记--33.Redis哨兵、redis简单事务
    js获取当前项目根路径URL (转自CSDN 红领巾-sunlight)
    架构师养成记--32.Redis高级(安全 主从复制)
    架构师养成记--31.Redis的几种类型
    架构师养成记--30.Redis环境搭建
    oracle split(转自--博客园 linbo.yang)
    架构师养成记--29.redis开篇
    129、Java面向对象之static关键字一(修改static变量)
    128、Java面向对象之对象的比较
  • 原文地址:https://www.cnblogs.com/jone-chen/p/7810343.html
Copyright © 2020-2023  润新知