|
| 1 | +## 二、正则表达式位置匹配 |
| 2 | + |
| 3 | +位置匹配,就是要匹配每个字符两边的位置。 |
| 4 | + |
| 5 | +在 `ES5` 中有6个位置: `^`,`$`,`\b`,`\B`,`(?=p)` 和 `(?!p)`。 |
| 6 | + |
| 7 | +另外把位置理解成空字符是非常有用的: |
| 8 | +```js |
| 9 | +/^^hello$$/.test('hello'); // true |
| 10 | +/^^^hello$$/.test('hello'); // true |
| 11 | +``` |
| 12 | + |
| 13 | +### 1. ^ 和 $ |
| 14 | + |
| 15 | +`^` 匹配开头,多行中匹配行开头。 |
| 16 | +`$` 匹配结尾,多行中匹配行结尾。 |
| 17 | +```js |
| 18 | +"hello".replace(/^|$/g, "#"); // "#hello#" |
| 19 | +"hello\nleo\nhaha".replace(/^|$/gm, "#"); |
| 20 | +/* |
| 21 | +#hello# |
| 22 | +#leo# |
| 23 | +#haha# |
| 24 | +*/ |
| 25 | +``` |
| 26 | +多行匹配模式使用 `m` 修饰符。 |
| 27 | + |
| 28 | +### 2. `\b` 和 `\B` |
| 29 | + |
| 30 | +`\b` 匹配单词边界,即 `\w` 和 `\W` 之间的位置,包括 `\w` 和 `^` 之间的位置,和 `\w` 和 `$` 之间的位置。 |
| 31 | +`\B` 和 `\b` 相反,即非单词边界,匹配中除去 `\b`,剩下的都是 `\B` 的。 |
| 32 | +也就是 `\w` 与 `\w`、 `\W` 与 `\W`、`^` 与 `\W`,`\W` 与 `$` 之间的位置。。 |
| 33 | + |
| 34 | +```js |
| 35 | +"[HI] Leo_1.mp4".replace(/\b/g,"#"); |
| 36 | +// "[#HI#] #Leo_1#.#mp4#" |
| 37 | + |
| 38 | +"[HI] Leo_1.mp4".replace(/\B/g,"#"); |
| 39 | +// "#[H#I]# L#e#o#_#1.m#p#4" |
| 40 | +``` |
| 41 | + |
| 42 | +### 3. `(?=p)` 和 `(?!p)` |
| 43 | + |
| 44 | +`p` 为一个子模式,即 `(?=p)` 匹配前面是 `p` 的位置,而 `(?!p)` 则匹配前面不是 `p` 的位置。 |
| 45 | +```js |
| 46 | +"hello".replace(/(?=l)/g, "#"); |
| 47 | +// "he#l#lo" |
| 48 | + |
| 49 | +"hello".replace(/(?!l)/g, "#"); |
| 50 | +// "#h#ell#o#" |
| 51 | +``` |
| 52 | + |
| 53 | +### 4. 相关案例 |
| 54 | + |
| 55 | +* 匹配数字千位分隔符 |
| 56 | + |
| 57 | +```js |
| 58 | +// 匹配最后一个逗号 |
| 59 | +"12345678".replace(/(?=\d{3}$)/g, ","); // "12345,678" |
| 60 | + |
| 61 | +// 匹配所有逗号 |
| 62 | +"12345678".replace(/(?=(\d{3})+$)/g, ","); // "12,345,678" |
| 63 | + |
| 64 | +// 匹配其余 |
| 65 | +"123456789".replace(/(?=(\d{3})+$)/g, ","); // ",123,456,789" |
| 66 | + |
| 67 | +// 修改 |
| 68 | +"123456789".replace(/(?!^)(?=(\d{3})+$)/g, ","); // "12,345,678" |
| 69 | + |
| 70 | +// 其他形式 |
| 71 | +"12345678 123456789".replace(/(?!\b)(?=(\d{3})+\b)/g, ","); |
| 72 | +// (?!\b) 等于 \B ,要求当前是一个位置,但不是 \b 前面的位置 |
| 73 | +// "12,345,678 123,456,789" |
| 74 | +``` |
| 75 | + |
| 76 | +* 数据格式化 |
| 77 | + |
| 78 | +```js |
| 79 | +let num = 1888; |
| 80 | +num.toFixed(2).replace(/\B(?=(\d{3})+\b)/g, ",").replace(/^/,"$$ "); |
| 81 | +// "$ 1,888.00" |
| 82 | +``` |
| 83 | + |
| 84 | +* 验证密码 |
| 85 | + |
| 86 | +```js |
| 87 | +// 密码长度 6-12 位数字或字母 |
| 88 | +let r = /^[0-9A-Za-z]{6,12}$/; |
| 89 | + |
| 90 | +// 必须包含一个字符(数字) + 密码长度 6-12 位数字或字母 |
| 91 | +let r = /(?=.*[0-9])^[0-9A-Za-z]{6,12}$/; |
| 92 | + |
| 93 | +// 必须包含两个个字符(数字和小写字符) + 密码长度 6-12 位数字或字母 |
| 94 | +let r = /(?=.*[0-9])(?=.*[a-z])^[0-9A-Za-z]{6,12}$/; |
| 95 | + |
| 96 | +r.test("aa1234566"); // true |
| 97 | +r.test("1234566"); // false |
| 98 | + |
| 99 | + |
| 100 | +// 密码长度 6-12 位数字或字母 |
| 101 | +// 即 不能全是数字 或 不能全是大写或小写字母 |
| 102 | +let r = /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/; |
| 103 | +``` |
0 commit comments