Skip to content

正则表达式

限定符:

字符描述
_匹配前面的子表达式零次或多次。
+匹配前面的子表达式一次或多次。
?匹配前面的子表达式零次或一次。
{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