正则表达式相关
# 正则表达式相关手写
# 将数字每千分位用逗号隔开
var string1 = "12345678",
string2 = "123456789";
reg = /(?!^)(?=(\d{3})+$)/g;
var result = string1.replace(reg, ',')
console.log(result);
// => "12,345,678"
result = string2.replace(reg, ',');
console.log(result);
// => "123,456,789"
// 用js
const split = (str) => {
const res = [];
let interger = str.split(".")[0];
let decimal = str.split(".")[1];
let s = "";
for (let i = interger.length - 1; i >= 0; i--) {
let len = interger.length - i;
s = interger[i] + s;
if (len % 3 === 0 || i === 0) {
res.unshift(s);
s = "";
}
}
if (decimal?.length) {
return res.join(",") + `.${decimal}`;
}
return res.join(",");
};
console.log(split("123456789.1234566"));
console.log(split("123456789"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 模版引擎
function render(template, data) {
const reg = /\{\{(\w+)\}\}/; // 模板字符串正则
if (reg.test(template)) {
// 判断模板里是否有模板字符串
const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段
template = template.replace(reg, data[name]); // 将第一个模板字符串渲染
return render(template, data); // 递归的渲染并返回渲染后的结构
}
return template; // 如果模板没有模板字符串直接返回
}
let template = "我是{{name}},年龄{{age}},性别{{sex}}";
let data = {
name: "姓名",
age: 18,
};
render(template, data); // 我是姓名,年龄18,性别undefined
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 实现loadash._get
function _get(source, path, defaultValue = undefined) {
// 将数组格式的路径转化成dot格式的,再拆分成key数组
// a[0].b -> a.0.b -> ['a', '0', 'b']
const paths = path.replace(/\[(\d+)\]/g, ".$1").split(".");
let result = source;
for (const p of paths) {
result = Object(result)[p]; // null 与 undefined 取属性会报错, 用Object包装一下
}
return result || defaultValue;
}
const object = { a: [{ b: { c: 3 } }] };
console.log(_get(object, "a[0].b.c"));
// => 3
console.log(_get(object, "a.b.c", "default"));
// => 'default'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 匹配十六进制颜色
表示一个16
进制字符,可以用字符组[0-9a-fA-F]
。
其中字符可以出现3或6次,需要是用量词和分支结构
const reg = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
var string = "#ffbbad #Fc01DF #FFF #ffE";
console.log(string.match(reg));
// [ '#ffbbad', '#Fc01DF', '#FFF', '#ffE' ]
1
2
3
4
5
2
3
4
5
# RGB
转#FFF
// 1. 利用 match() 方法,读取出 r 、 g 、 b
function rgb2hex(sRGB) {
var rgb = sRGB.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
return rgb.reduce((acc, cur) => {
var hex = (cur < 16? '0':'') + Number(cur).toString(16)
return acc + hex
}, '#').toUpperCase()
}
// 测试
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
// 2. rgb(255, 255, 255) 中 r 、 g 、 b 分别为连续的数字,所以我们可以利用正则 /\d+/g 获取取所有连着的数字
function rgb2hex(rgb) {
const rgb = rgb.match(/\d+/g);
const hex = (n) => {
return ("0" + Number(n).toString(16)).slice(-2);
}
return rgb.reduce((acc, cur) => acc + hex, '#').toUpperCase()
}
// 测试
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
// 3. 观察 rgb(255, 255, 255) 的每一个色值是透过 , 连接一起的,所以我们考虑是否能通过 split(',') 拆分出每一个色值,主要考虑两步
替换 rgb(255, 255, 255) 的部分字符( rgb 、 ( 、 ) )为 ''
拆分出每一个色值
function rgb2hex(sRGB) {
const rgb = sRGB.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
return "#" + ((1 << 24) + (Number(rgb[0]) << 16) + (Number(rgb[1]) << 8) + Number(rgb[2])).toString(16).slice(1).toUpperCase()}
// 测试
rgb2hex('rgb(255, 255, 255)')
// "#FFFFFF"
rgb2hex('rgb(16, 10, 255)')
// "#100AFF"
rgb2hex('rgb(1, 2, 3)')
// "#010203"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 判断url
只包含qq.com
http://www.qq.com // 通过
http://www.qq.com.cn // 不通过
http://www.qq.com/a/b // 通过
http://www.qq.com?a=1 // 通过
http://www.123qq.com?a=1 // 不通过
'http://www.baidu.com?redirect=http://www.qq.com/a' // 不通过
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
function check(url){
if(/^https?:\/\/w+\.qq\.com[^.]*$/.test(url)){
return true;
}else{
return false;
}
}
check('http://www.qq.com')
// true
check('http://www.qq.com.cn')
// false
check('http://www.qq.com/a/b')
// true
check('http://www.qq.com?a=1')
// true
check('http://www.123qq.com?a=1')
// false
check('http://www.baidu.com?redirect=http://www.qq.com/a')
// false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 匹配时间
匹配23:59 02:07 7:9
const regex = /^(0?[0-9]|1[0-9]|2[0-3]):(0?[0-9]|[1-5][0-9])$/;
console.log(regex.test("23:59"));
console.log(regex.test("02:07"));
console.log(regex.test("7:9"));
1
2
3
4
5
2
3
4
5
# 匹配dom
节点的id
要求从
<div id="container" class="main"></div>
提取出id="container"
const regex = /id=".*?"/;
const str = '<div id="container" class="main"></div>';
console.log(str.match(regex));
// 或者
var regex = /id="[^"]*"/;
const str = '<div id="container" class="main"></div>';
console.log(str.match(regex));
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 验证密码
密码长度6-12位,由数字、小写字符和大写字母组成,但必须至少包括2种字符。
var reg = /((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/;
console.log( reg.test("1234567") ); // false 全是数字
console.log( reg.test("abcdef") ); // false 全是小写字母
console.log( reg.test("ABCDEFGH") ); // false 全是大写字母
console.log( reg.test("ab23C") ); // false 不足6位
console.log( reg.test("ABCDEF234") ); // true 大写字母和数字
console.log( reg.test("abcdEF234") ); // true 三者都有
1
2
3
4
5
6
7
2
3
4
5
6
7
或者使用?!p
// 不能只出现数字 和 不能只出现小写字母和不能只出现大写字母
var reg = /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/;
console.log( reg.test("1234567") ); // false 全是数字
console.log( reg.test("abcdef") ); // false 全是小写字母
console.log( reg.test("ABCDEFGH") ); // false 全是大写字母
console.log( reg.test("ab23C") ); // false 不足6位
console.log( reg.test("ABCDEF234") ); // true 大写字母和数字
console.log( reg.test("abcdEF234") ); // true 三者都有
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 模拟trim
方法
function trim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
console.log( trim(" foobar ") );
// => "foobar"
1
2
3
4
5
2
3
4
5
# 将每个单词的首字母大写
?:
是非捕获分组
看栗子
var regex = /(?:ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// => ["abab", "ab", "ababab"]
function titleize(str) {
return str.toLowerCase().replace(/(?:^|\s)\w/g, function(c) {
return c.toUpperCase();
});
}
console.log( titleize('my name is epeli') );
// => "My Name Is Epeli"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 驼峰化
function camelize(str) {
return str.replace(/[-_\s]+(.)?/g, function(match, c) {
return c ? c.toUpperCase() : '';
});
}
console.log( camelize('-moz-transform') );
// => "MozTransform"
1
2
3
4
5
6
7
2
3
4
5
6
7
上次更新: 2022/03/14, 11:48:12