1. 修饰符
元字符是在正则表达式中有特殊含义的非字母字符,包含:
\:转义,将具有特殊意义的元字符转成原义文本字符.:除了换行以外的所有字符+:至少一个,一次或者多次;等同于{1,}?:至多一次,零或者一次等同于{0,1}*:任意次;等同于{0,}$:以 … 结尾^:字符类取反、或者以 … 开头|:或():分组{n,m}:用来包裹量词范围;最少出现n次,最多出现m次[]:用来包裹字符类 | 字符 | 含义 | | —- | —- | | \t | 水平制表符 | | \v | 垂直制表符 | | \n | 换行符 | | \r | 回车符 | | \0 | 空字符 | | \f | 换页符 | | \cX | 与X对应的控制字符(Ctrl+X) |
3. 字符类
一般情况下,正则表达式一个字符对应一个字符,如 ab\t,表示字符 ‘ab’ 以及一个制表符 tab
如果我们需要匹配一类字符,可以使用元字符 [] 来构建一个简单的类。所谓的类是指符合某些特性的对象,是一个泛指。如 [abc] 把字符 a 或 b 或 c 归为一类,只要有里面的一个,就能匹配。
'a1b2c3c'.replace(/[abc]/g, 'X'); // 'X1X2X3X'
中括号中出现的元字符一般都是代表本身含义的
let reg = /^[.]+$/;reg.test('.'); //=> true
中括号中的 - 有特殊含义,一般需要放在后面或者前面来代表本义
中括号中出现两位数,不是两位数,而是代表两个数中的任意一个
let reg = /^[12-65]$/g //=> 表示 1 或者 2-6 或者 5
3.1 字符类取反
使用元字符 ^ 创建反向类/负向类,就是不属于某类的内容。如 [^abc] 表示不是字符 a 或 b 或 c 的内容。
'a1b2c3c'.replace(/[^abc]/g, 'X'); // 'aXbXcXc'
3.2 范围类
使用 - 来连接两个字符,如 [a-z] 表示从 a 到 z 的任意字符,这是一个闭区间,包含 a 和 z 本身。
'a1b2d3x4z9'.replace(/[a-z]/g, 'Q'); // 'Q1Q2Q3Q4Q9'
在 [] 组成的类内部是可以连写的,如 [a-zA-Z]
注意:横线并不是元字符,但是在上面的情况是特指范围,不会匹配到 -
。如果需要匹配到横线,只需要在后面再加上横线。[a-z-]表示 a 到 z 以及横线。
3.3 预定义类
正则表达式提供预定义类来匹配常见的字符类。
正则表达式提供预定义类来匹配常见的字符类。
| 字符 | 等价类 | 含义 |
|---|---|---|
. |
[^\r\n] | 除了回车符和换行符之外的所有字符 |
| \d | [0-9] | 数字字符 |
| \D | [^0-9] | 非数字字符 |
| \s | [\t\n\x0B\f\r] | 空白字符 |
| \S | [^\t\n\x0B\f\r] | 非空白字符 |
| \w | [a-zA-Z_0-9] | 单词字符(字母、数字、下划线) |
| \W | [^a-zA-Z_0-9] | 非单词字符 |
4. 边界
正则表达式还提供了几个常用的边界匹配字符
^:以……开始$:以……结束\b:单词边界\B:非单词边界 ```javascript // 开头结尾匹配 ‘@12@12@1’.replace(/@./g, ‘0’); // ‘02020’ ‘@12@12@1’.replace(/^@./g, ‘0’); // ‘02@12@1’ ‘@12@12@1’.replace(/@.$/g, ‘0’); // ‘@12@120’
// 多行开头结尾匹配 ‘@12 @12 @12’.replace(/^@./g, ‘0’); // ‘02 // @12 // @12’
‘@12 @12 @12’.replace(/^@./gm, ‘0’); // ‘02 // 02 // 02’
// 单词边界 ‘This is a boy’.replace(/is/g, ‘0’); // ‘Th0 0 a boy’ ‘This is a boy’.replace(/\bis\b/g, ‘0’); // ‘This 0 a boy’ ‘This is a boy’.replace(/\Bis\b/g, ‘0’); // ‘Th0 is a boy’
<a name="VvClf"></a>## 5. 量词- `?`:出现零次或者一次(最多一次)- `+`:出现一次或多次(至少出现一次)- `*`:出现零次或者多次(任意次)- `{n}`:出现 n 次- `{n,m}`:出现 n 到 m 次- `{n,}`:至少出现 n 次注意:量词只作用于紧挨它的前一个正则字符> **贪婪模式**:正则表达式会在范围允许内尽可能多的匹配。<br />**非贪婪模式**:让正则表达式尽可能少的匹配,一旦匹配成功就不再继续匹配。默认正则表达式都是贪婪模式。如果需要实现非贪婪模式,只需要在量词后加上 `?` 即可。```javascript// 贪婪模式'123456789'.replace(/\d{3,6}/g, 'X'); // 'X78'// 非贪婪模式'123456789'.replace(/\d{3,6}?/g, 'X'); // 'XX78'
6. 分组
如果要匹配 destiny 连续出现的场景,如果使用 destiny{3},那么只会匹配到 destinyyy,而不是 destinydestinydestiny。
这时就需要使用 () 分组,使量词作用于分组。(destiny){3}
分组的作用:
- 提升优先级
- 分组匹配,可以理解成大正则里边的小正则
- 分组捕获 ```javascript let reg = /^1|8$/ ‘1’ //=> true ‘8’ //=> true ‘18’ //=> true
//=> 以 18 开头或 19 结束 let reg = /^18|19$/; ‘18’; //=> true ‘19’; //=> true ‘1819’; //=> true ‘181’; //=> true ‘819’; //=> true ‘189’; //=> true ‘119’; //=> true
//=> 如果只是想要匹配 18 或 19 let reg = /^(18|19)$/
<a name="BHIhK"></a>### 6.1 或使用 `|` 可以达到或的效果```javascript'ByronCasper'.replace(/Byron|Casper/g, 'X'); // 'XX''ByronsperByrCasper'.replace(/Byr(on|Ca)sper/g, 'X'); // 'XX
6.2 分组捕获
分组后,可以使用 $1 - $n 来表示各个分组匹配到的内容。即可以把分组内的内容捕获到。
'2018-05-11'.replace(/(\d{4})-(\d{2})-(\d{2})/g, '$2/$3/$1'); //=> 05/11/2018
6.3 分组引用
正则中,使用 \1、\2 等,来引用正则中出现的分组捕获的内容
//=> 匹配到四个字符的字母,其中第一个与最后一个一样,第二位与倒数第二位一样let reg = /^([a-Z])([a-Z])\2\1¥/;'oppo' //=> true'abba' //=> true
6.4 忽略分组
如果不希望捕获某些分组,只需要在分组内加上 ?:就可以,如 (?:Byron).(ok),这时,$1 就捕获 ok 分组匹配的内容
7. 前瞻
正则表达式从文本头部向尾部开始解析,称为“前”。
前瞻就是在正则表达式匹配到规则中的时候,向前检查是否符合断言,后顾方向相反。JavaScript 不支持后顾。
符合和不符合特定断言称为肯定/正向匹配和否定/负向匹配
| 名称 | 正则 |
|---|---|
| 正向前瞻 | exp(?=assert) |
| 负向前瞻 | exp(?!assert) |
正向前瞻:例 \w(?=\d),在是单词的基础上向前判断后面紧跟的是否是数字,这里只匹配单词,后面括号内的只是判断单词是否符合条件。
'a2*3'.replace(/\w(?=\d)/g, 'X'); // 'X2*3''a2*34v8'.replace(/\w(?=\d)/g, 'X'); // 'X2*X4X8'
负向前瞻:例 \w(?!\d),在单词的基础上向前判断后面紧跟的是否不是数字,这里也是只匹配单词,后面的只是判断条件。
'a2*3'.replace(/\w(?!\d)/g, 'X'); // 'aX*3''a2*34v8'.replace(/\w(?!\d)/g, 'X'); // 'aX*3XvX'
