Regular Expressions.md

Regular Expressions

Look Ahead & Behind

后置断言

1
2
3
4
5
6
7
8
9
10
11
12
var msg = 'Hello world';

msg.match(/(l.)/g);
// ['ll', 'ld']
msg.match(/(l.)$/g);
// ['ld']
msg.match(/(l.)(?=o)/g);
// 我要匹配l.的字符串,但是我希望这个字符串后面有'o'
// ['ll']
msg.match(/(l.)(?!o)/g);
// 我要匹配l.的字符串,但是我希望这个字符串后面没有'o'
// ['lo', 'ld']

前置断言

1
2
3
4
5
6
7
8
9

var msg = 'Hello World';

msg.match(/(?<=e)(l.)/g);
// 我要匹配l.的字符串,但是我希望这个字符串前面有'e'
// ['ll']
msg.match(/(?<!e)(l.)/g);
// 我要匹配l.的字符串,但是我希望这个字符串前面没有'e'
// ['lo', 'ld']

Named Capture Groups es2018

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var msg = 'Hello World';

// 使用括号的意思就是,我按这些匹配,但是最后出结果的时候也把我括号内的单独抽离出来, 成为结果之一
msg.match(/.(l.)/);
// ['ell', 'll']
msg.match(/([jkl])o Wor\1/);
// ['lo Worl']
// 让我们用捕获组重新写第一个例子
msg.match(/(?<groupName>l.)/);
// 把输出展开后, 我们得到了以下的内容:
// 0: "ll"
// 1: "ll"
// groups:-> 这个就是我们捕获组的, 自然,在这个下方是我们对捕获组的命名和匹配结果, 真的很实用, 我们的正则不再是一串又一串没有意义的数字了
// groupName: "ll"
// index: 2
// input: "Hello World"
// length: 2
msg.match(/(?<cap>[jkl])o Wor\k<cap>/);
// 对于这个正则,我没看懂的地方就是 \k 表达的是什么?

// 捕获组的应用场景: 替换
// 使用模板语法替换
msg.replace(/(?<cap>l.)/g, '-----------$<cap>----------');
// "He-----------ll----------o Wor-----------ld----------"
// 使用callback函数处理
msg.replace(/(?<cap>l.)/g, function re(...args) {
debugger
var [,,,,{cap}] = args;
return cap.toUpperCase();
});
// "HeLLo WorLD"

dotAll Mode ES2018

MDN内的描述

dotAll 属性表明是否在正则表达式中一起使用”s”修饰符(引入/s修饰符,使得.可以匹配任意单个字符)。dotAll 是一个只读的属性,属于单个正则表达式实例。

简而言之, 我使用了s的修饰符后, .可以匹配到

  1. U+000A 换行符(”\n”)
  2. U+000D 回车符(”\r”)
  3. U+2028 行分隔符(line separator)
  4. U+2029 段分隔符(paragraph separator)

为什么提出这个特性呢?因为历史因素, js中,正则表达式中的‘.’, 是元字符,本来是匹配所有的字符,但是就是不能匹配新的一行.

注意浏览器支持情况, 保留特性,暂时不要使用.

来看个例子:

1
2
3
4
5
6
7
8
9
var msg = `
The quick brown fox
jumps over the
lazy dog`;

msg.match(/brown.*over/);
// null
msg.match(/brown.*over/s);
// ["brown fox↵jumps over", index: 11, input: "↵The quick brown fox↵jumps over the↵lazy dog", groups: undefined]