重复的贪婪性

 {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}\1\d{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 \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>

Javascript正则表达式难点、重点的更多相关文章

  1. 浅析JavaScript正则表达式

    1.正则表达式的定义 正则表达式是一个描述字符模式的对象.JavaScript的RegExp类表示正则表达式,String和RegExp都定义了方法,后者使用正则表达式进行强大的模式匹配和文本检索与替 ...

  2. JavaScript正则表达式API

    1. [代码][JavaScript]代码     参考自<Core JavaScript Reference 1.5> JavaScript正则表达式有两种写法(随便哪种,看个人习惯): ...

  3. javascript正则表达式入门先了解这些

    前言 此内容由学习<JavaScript正则表达式迷你书(1.1版)>整理而来(于2020年3月30日看完).此外还参考了MDN上关于Regex和String的相关内容,还有ECMAScr ...

  4. JavaScript正则表达式,你真的知道?

    一.前言 粗浅的编写正则表达式,是造成性能瓶颈的主要原因.如下: var reg1 = /(A+A+)+B/; var reg2 = /AA+B/; 上述两个正则表达式,匹配效果是一样的,但是,效率就 ...

  5. 【JS】javascript 正则表达式 大全 总结

    javascript 正则表达式 大全 总结 参考整理了一些javascript正则表达式 目的一:自我复习归纳总结 目的二:共享方便大家搜索 微信:wixf150 验证数字:^[0-9]*$ 验证n ...

  6. 理清JavaScript正则表达式--上篇

    在JavaScript中,正则表达式由RegExp对象表示.RegExp对象呢,又可以通过直接量和构造函数RegExp两种方式创建,分别如下: //直接量 var re = /pattern/[g | ...

  7. 理清JavaScript正则表达式--下篇

    紧接:"理清JavaScript正则表达式--上篇". 正则在String类中的应用 类String支持四种利用正则表达式的方法.分别是search.replace.match和s ...

  8. JavaScript正则表达式详解(一)正则表达式入门

    JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...

  9. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

随机推荐

  1. 缓存-System.Web.Caching.Cache

    实现 Web 应用程序的缓存. 每个应用程序域创建一个此类的实例,只要应用程序域将保持活动状态,保持有效. 有关此类的实例的信息,请通过Cache的属性HttpContext对象或Cache属性的Pa ...

  2. DPDK报文分类与访问控制

    原创翻译,转载请注明出处. dpdk提供了一个访问控制库,提供了基于一系列分类规则对接收到的报文进行分类的能力.ACL库用来在一系列规则上执行N元组查找,可以实现多个分类和对每个分类查找最佳匹配(最高 ...

  3. BIND的安装配置

    简介 bind是dns协议的一种实现,也就是说,bind仅仅是实现DNS协议的一种应用程序 bind运行后的进程名叫named,不叫bind bind bind的配置文件在:/etc/named.co ...

  4. 第130天:移动端-rem布局

    一.关于布局方案 当拿到设计师给的UI设计图,前端的首要任务就是布局和样式,相信这对于大部分前端工程师来说已经不是什么难题了.移动端的布局相对PC较为简单,关键在于对不同设备的适配.之前介绍了一篇关于 ...

  5. SQL Server中使用自定义指定顺序排序

    比如需要对SQL表中的字段NAME进行如下的排序:张三(Z)李四(L)王五(W)赵六(Z) 如果想按 “ 张三.李四.王五.赵六”的顺序排序,则可以使用以下语句: order by charindex ...

  6. Android四大组件之Intent

    Intent不是android几大组件框架,但是确实是android 各大组件之间沟通的桥梁. 尤其Intent对于activity有很大的关系. 一下是我个人对task以及backstack的总结.

  7. BZOJ3551 ONTAK2010Peaks加强版(kruskal重构树+dfs序+主席树)

    kruskal重构树本质就是给并查集显式建树来替代可持久化并查集.将边按困难度从小到大排序后建出该树,按dfs序建主席树即可.查询时跳到深度最浅的满足在该重要度下已被合并的点,在子树内查询第k大. # ...

  8. 二分图匹配模板(dfs+bfs)

    dfs版: bool dfs(int u) { for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if(!vis[v]) { vis[ ...

  9. 洛谷 P3312 [SDOI2014]数表 解题报告

    P3312 [SDOI2014]数表 题目描述 有一张\(N*M\)的数表,其第\(i\)行第\(j\)列(\(1\le i \le n\),\(1 \le j \le m\))的数值为能同时整除\( ...

  10. 【loj#139】树链剖分

    #139. 树链剖分 题目描述 这是一道模板题. 给定一棵 $n$个节点的树,初始时该树的根为 111 号节点,每个节点有一个给定的权值.下面依次进行 $m$ 个操作,操作分为如下五种类型: 换根:将 ...