JS 正则表达式-速记通关小抄
[TOC]
基本元字符
| 元字符 | 含义 |
|---|---|
| . | 匹配除 换行符 以外的任何字符 |
| | | 逻辑或操作符 |
| [] | 定义一个集合,匹配集合中的一个字符,在这个集合里,所有的元字符都会失效,都会变为一个普通字符 |
| [^] | 对上面的集合取非 |
| - | 代表一个区间,例如[a-z] |
| \ | 表示下一个字符是特殊的,不能从字面上解释。比如 n 就代表n,如果在前面加上\,那么\n就代表了换行符。同理/a*/ 代表匹配a字符,如果在 * 前面加上\,就代表匹配 a* |
数量元字符
| 元字符 | 含义 |
|---|---|
| {m,n} | 匹配前面一个字符至少m次 至多n次重复。 |
| + | 记忆方式追加(+),起码得有一次 |
| * | 记忆方式乘法(*),可以一次都没有 |
| ? | 单独使用匹配前面一个表达式零次或者一次,相当于 {0,1},记忆方式,有吗?,有(1)或者没有(1),如果跟在任何量词*,+,?,{}后面的时候将会使量词变为非贪婪模式(尽量匹配少的字符),默认是使用贪婪模式。比如对 "123abc" 应用 /\d+/ 将会返回 "123",如果使用 /\d+?/,那么就只会匹配到 "1" |
:notebook: 再次解释
?元字符 的使用分为2种,一种是在普通字符后面A,一种是在数量元字符后面B。A情况很好理解,要么匹配0次,要么匹配1次;B情况是改变前一位量词的贪婪模式,将前一位量词转换为非贪婪模式,比如:
let x1 = 'https://12.10.30/xx-ctr.sty';
let regexp1 = /[1-9]+/;
let regexp2 = /[1-9]+?/;
x1.match(regexp1); // ['12']
x1.match(regexp2); // ['1']
位置元字符
| 元字符 | 含义 |
|---|---|
| ^ | 匹配以表达式 为开头的字符 |
| \$ | 匹配以表达式 为结尾的字符 |
| (?=p) | 匹配p前面的位置 |
| (?!p) | 匹配不是p前面的位置 |
标志元字符
| 元字符 | 含义 |
|---|---|
| g | 全局搜索 |
| i | 忽略大小写 |
| m | 多行匹配 |
分支结构
正则是是通过 | 符号来表达 或 的意思。具体如下:
let regexp1 = /p1|p2/;
// 匹配出来的结果,要么符合p1,要么符合p2, 绝对不会是pp2
请看下面的测试:
let str = 'https://12.10.30.110.26/xx-ctr.sty';
let regexp1 = /[1-9]+/;
let regexp2 = /[1-9]+?/g;
let regexp3 = /12|10/g;
let regexp4 = /12 | 10/g;
let regexp5 = /12 |10/g;
let regexp6 = /[1-9]+?/;
console.log('匹配出来的结果-1:', x1.match(regexp1)); // 12
console.log('匹配出来的结果-2:', x1.match(regexp2)); // 1、2、1、3、1、1、2、6
console.log('匹配出来的结果-3:', x1.match(regexp3)); // 12、10
console.log('匹配出来的结果-4:', x1.match(regexp4)); // null
console.log('匹配出来的结果-5:', x1.match(regexp5)); // 10
console.log('匹配出来的结果-6:', x1.match(regexp6)); // 1
引用分组
在正则表达式里,使用括号代表分组,以 左括号的出现顺序 代表 这是第几个分组。
那分组有啥用呢?它可以帮我们提取子数据。
let x1 = 'https://12.10.30.110.26/xx-ctr.sty';
let regexp7 = /([1-9]+\.)/;
x1.match(regexp7);
// 返回的结果的数据格式如下:
[
'12.', // 正则返回的结果
'12.', // 正则里第一个分组的结果
..., // 如果有第二个分组,那么就接着往后排
index: 8, // 正则返回的结果在字符串中的位置
input: 'https://12.10.30.110.26/xx-ctr.sty',
groups: undefined
]
接下来,我们栽看一下多括号的情况:
let x1 = 'https://12.10.30.110.26/xx-ctr.sty';
let regexp9 = /((https:)(\/\/))/; //第几个分组 对应 第几个左侧开括号
x1.match(regexp9);
// 返回的数据格式如下:
[
'https://', // 正则匹配的结果
'https://', // 第一个分组的结果 ((https:)(\/\/))
'https:', // 第二个分组的结果 (https:)
'//', // 第三个分组的结果 (\/\/)
index: 0,
input: 'https://12.10.30.110.26/xx-ctr.sty',
groups: undefined
]
有的时候,我们想在正则表达式里引用前面第一个分组对应的结果,或者是前面第二个分组对应的结果。
我们可以使用 \1来获取前面第一个分组对应的结果,\N 就是代表获取前面第N个分组对应的结果。
let regexp10 = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
let x1 = "2023-03/04";
regexp10.test(x1); // false