美文网首页
不积跬步之第三章--正则括号的作用

不积跬步之第三章--正则括号的作用

作者: 雨飞飞雨 | 来源:发表于2021-06-14 20:12 被阅读0次

括号?谁不会,不就是括起来的是一个子表达式吗?no no no

这篇文章的问题:

  • 什么是分组?
  • 什么是分组的引用?
  • 什么是反向引用?
  • 括号嵌套了怎么办?
  • \10 表示的什么呢?
  • 分组不存在会怎么样呢?
  • 分组后面有量词会怎么样呢?
  • 什么是非捕获括号?

什么是分组?

其实就是括号的作用,它提供了分组,以便我们引用它。

例如/a+/匹配连续出现的"a",而要匹配连续出现的"ab"时,就需要使用括号把他们括起来/(ab)+/.

其中括号是提供分组功能,让量词+作用于"ab"这个整体。

var regex = /(ab)+/g
var string = "ababa abbb ababab";
// => ["abab", "ab", "ababab"]

什么是分支结构?

分支结构就是我们之前学习的那个,使用管道符|来间隔多个子表达式。

(p1|p2)

它同样是我们括号的作用。

var regex = /^I love (JavaScript|Regular Expression)$/;
console.log( regex.test("I love JavaScript") );
console.log( regex.test("I love Regular Expression") );
// => true
// => true

什么是分组的引用呢?

这是括号一个非常重要的作用,有了它我们就可以进行数据提取,以及更强大的替换操作。

而要使用它,就必须配合使用实现环境的API

以日期为例,假设格式为yyyy-mm-dd。我们可以先写一个简单的正则。

var regex = /\d{4}-\d{2}-\d{2}/

可视化是这样的。

image.png

而如果添加了括号:

var regex = /(\d{4})-(\d{2})-(\d{2})/

可视化则是:

image.png
可以看到它们每一个被group所包裹。

正则引擎就是这么干的,在匹配过程中,给每一个分组都开辟一个空间,用来存储每一个分组匹配到的数据。

既然数据已经存储到空间里,那当然我们就可以引用它们。

提取数据

如果提取出年,月,日,可以这么做。

var regex = /(\d{4})-(\d{2})-(\d{2})/

var string = "2017-06-12";

console.log(string.match(regex)) 

返回的数据时这样:

[
  '2017-06-12',
  '2017',
  '06',
  '12',
  index: 0,
  input: '2017-06-12',
  groups: undefined
]

同样也可以使用正在实例对象的exec方法。

var regex = /(\d{4})-(\d{2})-(\d{2})/

var string = "2017-06-12";

console.log(regex.exec(string)) 

同时也可以使用构造函数的全局树形$1$9来获取。

var regex = /(\d{4})-(\d{2})-(\d{2})/

var string = "2017-06-12";
//正则操作就可以。同样也可以使用:
//regex.exec(string);
//string.match(regex);
regex.test(string);

console.log(RegExp.$1)
console.log(RegExp.$2)
console.log(RegExp.$3)

替换

既然我们已经拿到了引用,我们就可以玩一下花活,比如:替换。

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result);

其中后面的$2,$3,$1其实就是分组的引用。

反向引用

除了使用相应 API 来引用分组,也可以在正则本身里引用分组。但只能引用之前出现的分组,即反向引用。

比如要写一个正则来支持匹配下面三种格式:

2016-06-12
2016/06/12
2016.06.12

我们可以写出这样的正则:

var regex = /\d{4}(-|\/|\.)\d{2}-|\/|\.)\d{2}/
var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // true

其中/.需要转义,它的问题就是:虽然满足了以上的要求,但是同样匹配到了2016-06/12这样的数据。

如果我们想要前后一致,就需要使用反向引用了。

var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/

可视化是这样:


image.png

可以看到我们和之前的区别,\1它就是之前(-|\/|\.)的引用。无论它匹配到的是什么,那么这里就是什么。

既然\1是第一个分组,那么\2\3就是指第二个和第三个分组。

括号嵌套怎么办?

以左括号(开括号)为准。

如:

var regex = /^((\d)(\d(\d)))\1\2\3\4$/;
var string = "1231231233";
console.log( regex.test(string) ); // true
console.log( RegExp.$1 ); // 123
console.log( RegExp.$2 ); // 1
console.log( RegExp.$3 ); // 23
console.log( RegExp.$4 ); // 3

它的可视化是:

image.png

\10 表示的什么呢?

表示的是第10个分组。

引用不存在怎么办?

因为反向引用,是引用前面的分组,但是我们正在里引用了不存在的分组的时候,也不会报错,就是会匹配反向引用的字符本身。

例如\2就是匹配\2了,

分组后面有量词会怎样?

分组后面有量词的话,分组最终捕获到的数据时最后一次的匹配

var regex = /(\d)+/;
var string = "12345";
console.log( string.match(regex) );
// => ["12345", "5", index: 0, input: "12345"]

可以看到我们的分组(\d)捕获的数据时5.

同样反向引用,我们也还可以这样玩。

var regex = /(\d)+ \1/;
console.log( regex.test("12345 1") );
// => false
console.log( regex.test("12345 5") );
// => true

非捕获括号

之前稳重出现的括号,都会捕获它们匹配到的数据,以便后续引用,因此也称它们为捕获型分组和捕获型分支。

如果只想要括号最原始的功能,但不会引用它,既不在api里引用,也不在正则里引用。此时可以使用非捕获括号(?:p)(?:p1|p2|p3)

var regex = /(?:ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// => ["abab", "ab", "ababab"]

同理,第二个例子也可以是这样:

var regex = /^I love (?:JavaScript|Regular Expression)$/;
console.log( regex.test("I love JavaScript") );
console.log( regex.test("I love Regular Expression") );
// => true
// => true

相关文章

  • 不积跬步之第三章--正则括号的作用

    括号?谁不会,不就是括起来的是一个子表达式吗?no no no 这篇文章的问题: 什么是分组? 什么是分组的引用?...

  • 第三章 正则表达式括号的作用

    第三章 正则表达式括号的作用 不管哪门语言中都有括号。正则表达式也是一门语言,而括号的存在使这门语言更为强大。 对...

  • 不积跬步之正则的终章整理

    终于学习完了这一本《JavaScript正则表达式迷你书》,全书只有八十多页,而我却差不多学习了两周时间。从不熟悉...

  • 不积跬步之JavaScript 词法作用域

    昨天圣诞节,没有写,今天写两篇。奥利给!---现在是2021-1-4 还好不算晚,才隔了几天。 词法作用域 在第一...

  • shell正则

    1.特殊符号在shell正则中的作用 ^ 匹配正则表达式的开头,或若果在括号中,表示不匹配扩括号内的字符 $ 匹配...

  • 不积跬步之JavaScript什么是作用域 ?

    想到坚持这件小事,我为2020年的最后一个月的最后这段时间给自己开个好头。那就从每天坚持学习这件小事开始吧。每天一...

  • 不积跬步

    2018/10/25 星期四 晴 没想到二姐的高价小收音机比手机的辐射要强,放在床边睡觉,...

  • 不积跬步

    “不积跬步无以至千里”常用来激励。 可在自己身上发掘这句名言,却只有垃圾、肥肉和慢。 一个上午,断断续续收拾了两个...

  • 不积跬步

    生活中看起不起眼的事情,对一些人来说就是财富机遇 朋友在我们单位上班,也属于从别的单位挖过来的,老板慧眼识珠,两人...

  • js正则表达式教程(一)

    目录 第一章 正则表达式字符匹配攻略 第二章 正则表达式位置匹配攻略 第三章 正则表达式括号的作用 第四章 正则表...

网友评论

      本文标题:不积跬步之第三章--正则括号的作用

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