资讯专栏INFORMATION COLUMN

正则表达式- 捕获组

CntChen / 588人阅读

摘要:阅读此篇文章前需要具备以下知识正则表达式的基本语法捕获组是正则表达式里比较常用,也是比较重要的概念,我个人觉得掌握这部分的知识是非常重要的。我们知道的方法经常和正则表达式一起使用。

PS: 阅读此篇文章前需要具备以下知识:

正则表达式的基本语法

String​.prototype​.replace()

String​.prototype​.match()

捕获组(capturing group)是正则表达式里比较常用,也是比较重要的概念,我个人觉得掌握这部分的知识是非常重要的。
这篇文章内容不会很深入,但是尽量做到简单易懂又全面。接下来的内容主要是围绕以下7个点:

1: () 捕获组
2: (?:) non capturing group
3: (?=) positive lookahead
4: (?!) negative lookahead
5: (?<=) positive lookbehind
6: (?7: (?=), (?!), (?<=), (?

1: () 捕获组

/go+/

以上的正则表达式表示一个字母g后面跟上一个或者多个字母o,他能匹配go或者goooo。但是如果我们想+不只是运用到字母o上,而是运用到go这个整体上怎么办呢?办法就是给go加括号:

/(go)+/

为了全局匹配以及不考虑大小写,我们接下来会给我们的正则加上ig,这两个flag:

let reg = /(go)+/ig;
"go is g gogo".match(reg); //["go", "gogo"]

在上面的例子里面(go)就形成了一个捕获组(capturing group)。接下来看一个使用捕获组的例子来加深对它的理解:

let reg = /(d{2}).(d{2}).(d{4})/;
let originString = "10.25.2017";
reg.test(originString); //true
RegExp.$1; //10
RegExp.$2; //25
RegExp.$2; //2017

在上面这个例子里,我们有三组括号,形成了三个捕获组,正则表达式(在javaScript里就是我们的RegExp)会缓存捕获组所匹配的串,以$n表示,n就代表这第几个捕获组。

假如现在我们有一个需求:把显示格式为 10.25.2017 的时间改为 2017-10-25 格式。

我们知道String的replace()方法经常和正则表达式一起使用。在replace()方法里,我们可以直接使用捕获组的结果:

let reg = /(d{2}).(d{2}).(d{4})/;
let originString = "10.25.2017";
let newString = originString.replace(reg, "$3-$1-$2");
console.log(newString);//"2017-10-25"

2: (?:) non capturing group 非捕获型分组
有的时候我们可能只想匹配分组,但是并不想缓存(不想捕获)匹配到的结果,就可以在我们的分组模式前面加上?:。例如上面的时间的例子,我们不想捕获第一个分组的结果,就可以这么做:

let reg = /(?:d{2}).(d{2}).(d{4})/;
let originString = "10.25.2017";
reg.test(originString); //true
RegExp.$1; //25
RegExp.$2; //2017
originString.match(reg);// ["10.25.2017", "25", "2017", index: 0, input: "10.25.2017", groups: undefined]

从上面的例子可以看出,我们的正则表达式依然是匹配的(test()的结果依然为true),但是RegExp.$1不是数字10,而是25,因为我们在第一个括号里加了?:,10就不会被捕获。match()的执行结果也会受?:的影响:match()的结果里不再有‘10’。

3: (?=) positive lookahead 正向前瞻型捕获
有一个句子:1 apple costs 10€. 我们想要匹配€前面的价格(这里是一个数字),但是注意不能匹配到句子开头的数字1。这种情况,就可以用到正向前瞻型捕获:

let reg = /d+(?=€)/g;
let reg1 = /d+/g;
let str = "1 apple costs 10€";
str.match(reg); //["10"]
str.match(reg1); //["1", "10"]

上面的例子里面reg1就只需要匹配数字,对于数字后面跟什么并没有要求,所以它能匹配到1,10。但是reg使用了前瞻型匹配,就只能匹配到10。
或许你已经能从上面的对比里了解到什么是正向前瞻型捕获了,意思是:

/x(?=y)/ 匹配x, 但是必须在x的【后面】【是】y的情况下

4: (?!) negative lookahead 负向前瞻型捕获
上面我们了解了什么是正向前瞻型匹配,从字面意思也能猜出来负向前瞻型捕获就是:

/x(?!y)/ 匹配x, 但是必须在x的【后面】【不是】y的情况下

例如下面的例子,我们要匹配数字1,而不要€前面的2,就可以用到?!

let reg = /d+(?!€)/g;
let str = "1 apple costs 2€";
str.match(reg); ["1"]

5: (?<=) positive lookbehind 正向后顾型捕获
后顾型和前瞻型正好相反,意思就是:

/(?<=y)x/ 匹配x, 但是只在【前面】【有】y的情况下
来看一个例子:

let str = "1 turkey costs $2";
console.log( str.match(/(?<=$)d+/g) ); //["2"]

这里的要求是前面有$的数字,所以这里匹配到了数字2,而没有1.

6: (?
负向就是与正向相反,那么负向后顾型捕获就是:

/(?<=y)x/ 匹配x, 但是只在【前面】【没有】y的情况下

来看一个例子:

let str = "1 turkey costs $2";
console.log( str.match(/(?

7: (?=), (?!), (?<=), (?
默认情况下上面的前瞻后顾4种都是默认不匹配捕获组里面的内容的,也就是不匹配括号里的条件的。例如我们的正向前瞻/d+(?=€)/g,只会匹配到数字,并不会匹配到€。如果我们想要也匹配到€怎么办呢?答案就是给€也包上一个括号:

let str = "1 turkey costs 2€";
let reg = /d+(?=(€))/; 
str.match(reg); //["2", "€", index: 15, input: "1 turkey costs 2€", groups: undefined]

这样就匹配到了数字2和它后面的€。

下面再来看看后顾型:

let str = "1 turkey costs $2";
let reg = /(?<=($|£))d+/;
console.log( str.match(reg) ); //["2", "$", index: 16, input: "1 turkey costs $2", groups: undefined]

需要特别注意到的一点是,对于后顾型,虽然条件在匹配项的前面,但是匹配出来的结果顺序依然是条件在匹配项的后面。所以这里match()出来的结果是2在$的前面。

PS:截止到目前为止(ES2015),JavaScript还不支持后顾型匹配,就是说(?<=), (?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104000.html

相关文章

  • Python正则达式很难?一篇文章搞定他,不是我吹!

    摘要:正则表达式语法字符与字符类特殊字符以上特殊字符要想使用字面值,必须使用进行转义字符类包含在中的一个或者多个字符被称为字符类,字符类在匹配时如果没有指定量词则只会匹配其中的一个。 1. 正则表达式语法 1.1 字符与字符类 1 特殊字符:.^$?+*{}| 以上特殊字符要想使用字面值,必须使用进行转义 2 字符类 1. 包含在[]中的一个或者多个字符被称为字符类,字符类在匹配时如果没有指...

    dcr309duan 评论0 收藏0
  • TRY REGEX:正则达式交互式入门教程 翻译&解答

    摘要:写一个正则表达式来测试变量中是否包含字符串。用函数给出不使用字符,但和等价的正则表达式。第十四课标志全局匹配标志第二个常用的标志是全局匹配标志,用字母表示。写出一个正则表达式来检验合法性。非捕获组的主要用途是给一个组赋予量词。 TRY REGEX 是一个交互式的正则表达式学习项目项目地址:https://github.com/callumacra...在线地址:http://tryre...

    李义 评论0 收藏0
  • java正则表式的使用

    摘要:直接使用正则表达式对输入的字符串进行匹配,匹配成功则返回使用正则表示式,进行字符串分割进行匹配操作,如果匹配成功,这三个方法都会返回其中,是在源字符串中找出和正则表达式匹配的字符串。 概念 正则表达式 在阅读本文前,你应该已经了解了正则表达式的基本概念以及如何书写正则表达式。如果对正则表达式不是太了解,或者想更深入地了解正则表示式,请点击这里。 捕获组 捕获组能够让我们方便地从正则表达...

    zoomdong 评论0 收藏0
  • 正则达式在 ES2018 中的新写法

    摘要:自从年推出标准第版以来,正则表达式已成为语言的一部分。最后,如果在正则表达式中使用了命名捕获组,则将它们放在属性中。支持与相同语法的命名组已经模仿了的正则表达式语法。下面是一个例子此正则表达式在句子中查找连续的重复单词。 翻译:疯狂的技术宅原文:https://www.smashingmagazine.... 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推...

    lanffy 评论0 收藏0

发表评论

0条评论

CntChen

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<