最近在研究正则,看了很多文章发现写的都非常好,但是真给几个题目做做,还真做不出来,下面我们就根据题目去讨论一下正则,相信通过这些题目,我们再去看大佬的文章或许会收获更多!
一、创建正则
- 构造函数创建
const reg = new RegExp(/a/); // 匹配含有字母a
- 正则字面量
const reg2 = /abc/; // 匹配字母abc
const reg3 = /[abc]/; // 匹配字母a,或者b,或者c
二、正则的组成
- 正则的组成: 普通字符 + 元字符
- 普通字符: 大小写字母, 数字
- 元字符: 在正则里面有特殊含义的
元字符
| 匹配区间 | 正则表达式 | 含义 |
|---|---|---|
| 除了换行的任意的字符 | . | 句号,除了句子结束符 |
| 数字[0-9] | \d | digit |
| 非数字 除了[0-9] | \D | not digit |
| 字符(大小写字母 数字 _) | \w | word |
| 非字符 | \W | not word |
| 不可见字符(空格 换行 制表符(tab)) | \s | space |
| 可见字符 | \S | not space |
| 但是如果我想要匹配'.'这个符号就要使用 '\' 进行转译 |
/ 匹配小数点
// 需要对 . 进行转义, \.
console.log(/\./.test("100.5")); // true
console.log(/\./.test("1005")); // false
转译字符还有一个作用,就是这个字符不是特殊字符,使用转译符号后就让他拥有了特殊的含义。比如说元字符,还有一些特殊字符
| 特殊字符 | 正则表达式 | 含义 |
|---|---|---|
| 换行符 | \n | new line |
| 回车符 | \r | return |
| 空白符 | \s | space |
| 制表符 | \t | tab |
| 我们来做一些题目 |
var reg1 = /abc/
console.log(reg1.test("a")); // false
console.log(reg1.test("aabca")); // true
匹配abc
var reg2 = /\d/
console.log(reg2.test('abc123')) // true
reg2 = /\D/
console.log(reg2.test('abc123')) // true
匹配数字和非数字
var reg3 = /\./
console.log(reg3.test('100.5')) // true
console.log(reg3.test('1005')) // false
如果我要匹配两个怎么办呢?
console.log(/(f|b)oot/.test("f")); // false
console.log(/(f|b)oot/.test("foot")); // true
console.log(/(f|b)oot/.test("boot")); // true
console.log(/(f|b)oot/.test("fboot")); // true
由题目的最后一题我们引出[] 如果我要匹配a或者b或者c该怎么办?
let reg = /a|b|c/
let reg1 = [abc]
[]的解释说明
- [] ===> 在正则里面一个字符的位置,在[]里面可以出现的字符,可以使用“-”表示范围
- [^] ===> ^在[]里面,表示非的意思
- [^abc] ===> 表示不能是a,或者不能是b,或者不能是c,除了abc都行
// /[abc]/ ==> a 或者 b 或者 c
// /[a-z]/ ==> 是一个字符, 字符可以是 a-z 的其中一个
// /[A-Z]/ ==> 是一个字符, 字符可以是 A-Z 的其中一个
// /[0-9]/ ==> 是一个字符, 字符可以是 0-9 的其中一个
// /[a-zA-Z0-9]/ ==> 是一个字符, 字符可以是 a-z 或者 A-Z 或者 0-9 的其中一个
console.log(/[abc]/.test("a")); // true
console.log(/[abc]/.test("b")); // true
console.log(/[abc]/.test("c")); // true
console.log(/[a-z]/.test("a123")); // true
console.log(/[a-z]/.test("123")); // false
console.log(/[^abc]/.test("abc")); // false
console.log(/[^abc]/.test("ade")); // true, 只要满足了正则的规律,就返回true
console.log(/[^0]/.test("0123")); // true
console.log(/[^0]/.test("0")); // false
三、循环与重复
| 正则表达式 | 含义 | 解释 |
|---|---|---|
| * | 出现 0次到多次 {0,} | >= 0 |
| + | 出现 1次到多次{1,} | >= 1 |
| ? | 出现 0次到1次{0,1} | 0 || 1 |
| {m,n} | 出现 m次到n次 | |
| {m,} | 出现 m次以上 | |
| {m} | 出现m次 | |
| {0,m} | 出现最多m次 |
我觉得先做一个面试题,根据面试题我们在进行讲解效果会好很多
const target = '111,222,333,aa, ,!@?'
// 1.1 匹配target中的数字
// 1.2 将特殊符号(除了','号)替换为\*
target.match(/\d+/g)
target.replace(/[^,\w]/g,'*')
// 讲解:
// 1. 字符串的match()方法:
// 会返回数组,数组里面就是字符串中符合正则的每一项, 匹配不到返回null
// 2. 元字符 + 适用于要匹配同个字符出现1次或多次的情况 >=1
元字符 ? 0 | 1
元字符 * >= 0
特定次数:
{x}: x次
{min, max}: 介于min次到max次之间
{min, }: 至少min次
{0, max}: 至多max次
题目里提到了g这就引出了
四、字符串边界
接下来我们还需要位置边界的匹配。在长文本字符串查找过程中,我们常常需要限制查询的位置。比如我想要全局匹配,我想要不区分大小写
| 边界和标志 | 正则表达式 | 含义 |
|---|---|---|
| 单词边界 | \b | boundary |
| 非单词边界 | \B | not boundary |
| 字符串开头 | 箭头就是开头 | |
| 字符串结尾 | $ | 做事的结果都会有钱$ |
| 多行模式 | m | multiple of lines |
| 忽略大小写 | i | ignore case, case-insensitive |
| 全局模式 | g | global |
- \b和\B
\b是单词边界,具体就是\w和\W之间的位置,也包括\w和^之间的位置,也包括\w和$之间的位置。
const reg1 = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
console.log(reg1); // "[#JS#] #Lesson_01#.#mp4#"
const reg2 = "[JS] Lesson_01.mp4".replace(/\B/g, '#');
console.log(reg2); // "#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4"
- ^和$
// 把字符串的开头和结尾加上|
const reg1 = "hello".replace(/^|$/g,'|')
console.log(reg1) // "|hello|"
- g和m
const result = "I\nlove\njavascript".replace(/^|$/gm, '#');
console.log(result);
/*
#I#
#love#
#javascript#
*/
// 给一个连字符串例如:get-element-by-id转化成驼峰形式。
let str = 'get-element-by-id'
let reg = /-\w/g
str.replace(reg,v => v.slice(1).toUpperCase())
// 验证座机电话
// 规律:021-29109210 0557-10928380
// 区号:3-4位数字 首位是0 次位不能为0的数字 1-2位数字
// 座机:7-8位数字 首位2-8的数字 6-7位数字
let reg = /^0\[1-9]\d{1,2}-[2-8]\d{6,7}$/
// 验证手机号码
// 规律:13900000000
// 十一位数字 首位1 次位3-9 9位数字
let reg = /^1[3-9]\d{9}$/
// 验证邮箱
// 规律:数字 字母 _ . - @ 数字 字母 _ .字母
let reg = /^[\w\.-]+@\w+(\.[a-z]+)+$/
// 验证姓名
// 规律:汉字 2-6位
let reg = /^[\u4e00-\u9fa5]{2,6}$/
当我以为正则学的差不多的时候,有一个题目难住了我
// 数字的千位分隔符表示法
把"12345678",变成"12,345,678"
- (?=p)和(?!p)
(?=p),其中p是一个子模式,即p前面的位置
比如(?=l),表示'l'字符前面的位置,例如:
var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"
而(?!p)就是(?=p)的反面意思,比如:
var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
// => "#h#ell#o#"
经过上面的总结现在给出字符串的千分位分隔符表示法
let string = "12345678123456789";
const reg = /(?!\b)(?=(\d{3})+\b)/g;
let result = string.replace(reg, ',')
console.log(result);
// => "12,345,678,123,456,789"
另一种数字的千分位分隔符表示法(不推荐)
let num = 10329203.23
console.log(num.toLocaleString())