正则表达式
限定符:
字符 | 描述 |
---|---|
_ | 匹配前面的子表达式零次或多次。 |
+ | 匹配前面的子表达式一次或多次。 |
? | 匹配前面的子表达式零次或一次。 |
{n} | n 是一个非负整数。匹配确定的 n 次 |
{n,} | n 是一个非负整数。至少匹配 n 次。 |
{n,m} | m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。 |
普通字符
字符 | 描述 |
---|---|
[a-zA-Z0-9] | 匹配括号里存在的 : "465778931".match(/[2315778646]/g) |
[^a-z] | 匹配不存在的 |
. | 除换行符的单个字符 |
\w | 匹配字母数字下划线 |
\d | 匹配所有数字 |
\s | 匹配空白字符 包括换行 |
\S | 匹配非空白字符,不包括换行符 |
() | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用 |
/<._>/ | 贪婪 |
/<._?>/ | 非贪婪 |
尾标记:
- g :全局
- i : 不区分大小写
- m : 多行
定位符
^
匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。$
匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。\b
匹配一个单词边界,即字与空格间的位置。\B
非单词边界匹配。
选择符
exp1(?=exp2)
:查找 exp2 前面的 exp1。(?<=exp2)exp1
:查找 exp2 后面的 exp1。exp1(?!exp2)
:查找后面不是 exp2 的 exp1。(?<!exp2)exp1
:查找前面不是 exp2 的 exp1。
练习:
最简版身份证:
/^[0-9]{15}$|^[0-9]{18}$|^[0-9]{17}[xX]$/.test('12345678912345612X')
密码长度大于等于 12 位,必须包含字符 、数字、特殊字符
._~!@#$^&*'
/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[._~!@#$^&*])([0-9a-zA-Z._~!@#$^&*]){12,}$/
判断 url 是否合规
/^(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?(\/#)?(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/
手写实现
防抖函数:
js
function debounce(fun, delay, immediate) {
let time = null;
return function () {
if (time) {
clearTimeout(time);
}
if (immediate) {
// 立即执行的情况
let exec = !time;
time = setTimeout(() => {
time = null;
}, delay);
if (exec) {
fun.apply(fun, arguments);
}
} else {
// 延时执行的情况
time = setTimeout(() => {
fun.apply(fun, arguments);
}, delay);
}
};
}
let deboundceCli = debounce((e) => console.log(e), 500);
document.addEventListener("click", function () {
deboundceCli("jty");
});
节流函数
js
function throttle(fun, delay) {
let time = 0;
return function () {
if (Date.now() - time > delay) {
time = Date.now();
fun.apply(this, arguments);
}
};
}
let throttleCli = throttle((e) => console.log(e), 1000);
window.document.addEventListener("scroll", function () {
throttleCli("jty11");
});
柯里化:
js
function curry(fn) {
// rest arguments 效果一样
function inner(...rest) {
if (fn.length === rest.length) {
fn.apply(this, rest);
} else {
return inner.bind(this, ...rest);
}
}
return inner;
}
function fn(a, b, c) {
console.log(a + b + c);
}
let cfn = curry(fn);
cfn(1)(2)(3);
函数组合:
js
function compose(arrFn) {
return function (val) {
return arrFn.reduce((a, fn) => {
return fn.call(null, a);
}, val);
};
}
const foo = (a) => {
return a + 1;
};
const bar = (a) => a + 1;
let comp = compose([foo, bar]);
console.log(comp(5));
其他
forin 和 Object.keys 区别:(枚举跟原型链)
区别就是 Object.keys( )不会走原型链,而 for in 会走原型链;
Reflect.ownKeys 返回所有的属性不管是不是可枚举, 不能获取原型链
Object.keys 返回可枚举的属性
js
let parent = { a: 1 };
let child = { b: 2 };
child.__proto__ = parent;
Object.keys(child);
//['b']
for (let key in child) {
console.log(key);
}
// b , a