正则

为什么要学正则,正则这东西可真的太神奇了,可以把字符串弄得服服帖帖的,不然你跟字符串相处就不是那么亲昵 hhhh


参考

开课吧的网课~这里是个整理


入门:提取数字

给你一串字符串 123jkh123hjk213h213jk43bmnb,请把这里的数字提取出来

第一种方法,写个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getNumber(str) {
let arr = [];
let temp = "";
for (let i = 0; i < str.length; i++) {
// console.log(typeof str[i]);
if (!isNaN(str[i])) {
// console.log("数字");
temp += str[i];
} else {
// console.log("非数字");
if (temp != "") {
arr.push(temp);
temp = "";
}
}
}
if (temp != "") {
arr.push(temp);
}
return arr;
}
let res = getNumber(str);
console.log(res);

判断字符串中是不是数字可以用isNaN()

第二种方式:正则

1
2
3
let reg = /\d+/g;
let arr = str.match(reg);
console.log(arr);

详解

创建正则

  • 字面量
  • 构造函数
1
2
3
let str = "dsajlkjrwlj";
let regExp1 = /\d+/g; // 字面量创建正则
let regExp2 = new RegExp("\\d+", "g"); // 构造函数创建正则,第二个参数是匹配模式

跟正则相关的字符串方法

split

1
2
3
let str = "babbabbbabbbb";
let arr = str.split(/a/);
console.log(arr); // (4) ["b", "bb", "bbb", "bbbb"]

replace

1
2
3
4
let str = "abcd1234";
let reg = /\d+/g;
let res = str.replace(reg, "*");
console.log(res); // abcd*

可以用来做敏感词过滤,可以看下一个例子

1
2
3
4
5
6
7
8
9
10
let str = "澳门赌场,真人发牌,av女优";
// 教育部 、 人员;
let reg = /赌场|av|女优/g;
// let res = str.replace(reg,"*");
let res = str.replace(reg, function (arg) {
// 回调函数中能够拿到匹配到的结果
str.replace(reg, "*");
return "*".repeat(arg.length);
});
console.log(res); // 澳门**,真人发牌,****

match

1
2
3
4
5
6
7
8
let str = "abcd1234";
let reg1 = /\d+/g;
let reg2 = /\d+/;
// 如果不是全局匹配的话,他会拿到很多详细的
let res1 = str.match(reg1);
let res2 = str.match(reg2);
console.log(res1); // ["1234"]
console.log(res2); // ["1234", index: 4, input: "abcd1234", groups: undefined]
1
2
3
4
5
6
// 4.search:匹配第一个符合结果的索引值位置;如果找不到 就返还-1;
// 忽略全部匹配;所以加g 或者 不加g 没什么区别
let str = "fdsfda323fdaf1232";
let reg = /\d+/;
let res = str.search(reg);
console.log(res);

元字符

啥叫元字符呢?

元字符:正则中有特殊含义的非字母字符;
比方说. *(0 次或者多次) + ? $ ^ | \ () [] {};

下面会一一介绍每个元字符的作用

. 除了 \n \r \u2028\u2029 以外的所有字符

\ 转义:将特殊含义转换成字面量含义

* 出现零次或多次

^ 开头、$结尾、\w 字母、数字、下划线

1
2
3
4
5
6
7
// let str = "cde__111fg";
let str = "cde__111f"; // 测试的话改这里
// let reg = /^c\w+g$/g;
let reg = /^c\w+g$/g;
// let res = reg.test(str);
let res = str.match(reg);
console.log(res);

[] 字符集合

1
2
3
4
5
6
let str = "dffdabfds123fdabfdb435afdsa";
// let reg = /a|b/g;
let reg = /[ab]/g;
let reg = /[^ab]/g; // 尖括号写在集合里面,就是取反的意思
let res = str.replace(reg, "*");
console.log(res);
1
2
3
// 以下两个意思相同
let reg1 = /\d+/g;
let reg2 = /[0-9]+/g;
1
2
3
4
// 多种方式
// . === [^\r\n]
// \d === [0-9];
// \w === [a-zA-Z_0-9];

\b 边界:非 \w 都被称为边界;

1
2
3
4
5
6
// 想要匹配 前面的is ,而不是 this 中的 is
let str = "is this a book?";
let reg = /\bis\b/g;
// let reg = new RegExp("\\bis\\b","g");
let arr = str.match(reg);
console.log(arr);

{} 说明匹配的数量

() 分组

1
2
3
4
5
6
7
8
9
10
11
let str = "abfdssafdsababljljabssfd";
/*
? --- {0,1}
+ --- {1,}
* --- {0,}
{2};
*/
let reg = /s{2}/g; // {} 指定数量
let reg = /(ab){2}/g; // abb
let res = str.replace(reg, "*");
console.log(res);

$反向引用:根据分组

1
2
3
4
5
6
7
8
9
10
11
// 转换时间格式:2019-10-19  ---->  19/10/2019;
// 反向引用;
let mytime = "2019-10-19";
let reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g;
let reg1 = /(\D+)/g;
let res = mytime.replace(reg, "$3/$2/$1"); // 正则里的东西,拿过来引用,通过分组
console.log(RegExp.$1); // 2019

let res1 = mytime.replace(reg1, "-"); //
console.log(RegExp.$1); // -
console.log(res); // 通过 RegExp 反向引用是有顺序的,应该是保留最后一次用正则的结果

命名分组:?<分组名> ES2018 新增特性

1
2
3
4
let str = "$name=zhangsan&age=20";
let reg = /\$(?<str>\w+)/;
let res = str.match(reg);
console.log(res.groups.str);

零宽断言

这是 ES2018 也就是 ES9 的语法。

我理解的啊

所谓的正向反向是针对 断言 的,(断言的意思就是猜测,不确定的东西。比方说 iphone6iphone7 等等,这些数字就是需要猜测的)

正向断言就是:猜后面,改前面
反向断言就是:猜前面,改后面

正向肯定断言

分组之后 (?=)

1
2
3
4
5
6
let str = "iphone3iphone4iphone11iphoneNumber";
// iphone 换成“苹果”;
// 匹配的条件是 iphone 后面必须接 一到两个 数字
let reg = /iphone(?=\d{1,2})/g;
let res = str.replace(reg, "苹果");
console.log(res); // 苹果3苹果4苹果11iphoneNumber

正向否定断言

(?!)

1
2
3
4
5
let str = "iphone3iphone4iphone11iphoneNumber";
// iphone 换成“苹果”;
let reg = /iphone(?!\d{1,2})/g;
let res = str.replace(reg, "苹果");
console.log(res); // iphone3iphone4iphone11苹果Number

负向肯定断言

(?<=)

1
2
3
4
5
// let str = "10px20px30pxipx";
// // px-->像素;
// let reg = /(?<=\d{2})px/g;
// let res = str.replace(reg,"像素");
// console.log(res); // 10像素20像素30像素ipx

负向否定断言

(?<!)

1
2
3
4
5
6
// 负向否定断言;猜前面,改后面
let str = "10px20px30pxipx";
// px-->像素;
let reg = /(?<!\d{2})px/g;
let res = str.replace(reg, "像素");
console.log(res); // 10px20px30pxi像素

匹配模式

1
2
3
4
5
6
7
8
9
10
// 匹配模式
// g:全局匹配
// i:忽略大小写;
let str = "aaaaaAAAAAA";
let reg = /a/g;
let reg1 = /a/gi;
let res = str.replace(reg, "*");
let res1 = str.replace(reg1, "*");
console.log(res); // *****AAAAAA
console.log(res1); // ***********

m 多行匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
let str = `aaaaa
aaaaa`;
let reg1 = /^\w/g;
let reg2 = /^\w/gm;
let res1 = str.replace(reg1, "*");
let res2 = str.replace(reg2, "*");
console.log(res1);
/* *aaaa
aaaaa */

console.log(res2);
/* *aaaa
*aaaa */

s 可以让 . 匹配到换行符

1
2
3
4
5
6
7
8
9
let str = `<div>som
e value..</div>`;
let reg1 = /<div>.*<\/div>/g;
let reg2 = /<div>.*<\/div>/gs;
// “\” 转义:将特殊含义转换成字面量含义;
let res1 = reg1.test(str);
let res2 = reg2.test(str);
console.log(res1); // false
console.log(res2); // true

u

1
2
3
// `\uD842\uDFB7` 是 汉字 𠮷
console.log(/^.$/.test("\uD842\uDFB7")); // false
console.log(/^.$/u.test("\uD842\uDFB7")); // true

y 粘性模式,只匹配第一个,之后的就匹配不到了。

1
2
3
4
5
6
7
8
let str = "12ab34cd";
let reg1 = /\d+/g;
let reg2 = /\d+/gy;
console.log(reg1.exec(str)); // ["12", index: 0, input: "12ab34cd", groups: undefined]
console.log(reg1.exec(str)); // ["34", index: 4, input: "12ab34cd", groups: undefined]

console.log(reg2.exec(str)); // ["12", index: 0, input: "12ab34cd", groups: undefined]
console.log(reg2.exec(str)); // null

都滑倒底了,如果对你有帮助的话,点个赞再走吧~在这里插入图片描述