一 前言

正则表达式入门实践系列文章适合熟悉至少使用过正则表达式的同学,在文章开始的时候我们都会带着问题去思考如何正确应用正则表达式解决出现的问题,在解决问题的过程中增长你的知识,提高你的实践能力。所以该系列文章是偏实践的文章,读者一定要手动编写正则表达式提高自己的记忆。笔者能力有限,文章有疏漏之处,还请留言指正。

二 正文

1.从一道面试题谈正则表达式

问题:正则表达式将阿拉伯数字每隔三位为一逗号分离
例如:11500000 -> 11,500,000

提示:正则表达式都是从左向右匹配的,而这个问题好像是从右向左的规则。但是不要忘了JS字符串强大的反转能力。最重要的是如何正确处理三个数字一组,零宽项断言用过吗?

"11500000".split("").reverse().join("").replace(/(\d{3})(?=[^$])/g, "$1,").split("").reverse().join("");
(1). (?=[^$]) 会匹配除字符除末尾所有的位置
(2). /(\d{3})(?=[^$])/ 会匹配连续的三个数字,并且这三个数字不能在字符串的末尾
(3)replace(/(\d{3})/g, "$1,"),如果字符串长度刚好是三的倍数,那最后三个字符后也会加上逗号。比如 123456789.replace(/(\d{3})/g, "$1,"); // 123,456,789,

这里用到的正则表达式就是:

const pattern = /(\d{3})(?=[^$])/g;

//千万不要写成:
//const pattern = '/(\d{3})(?=[^$])/g';
//这样pattern就不是正则了,而是真正的字符串

正则表达式的创建方式有两种:

(1)字面量形式,用//包裹着,如上:/(\d{3})(?=[^$])/,其中的g代表全局匹配
(2)函数的形式,如:new RegExp('(\\d{3})(?=[^$])','g');

(1)与(2)的区别:

1)最重要的一点,(2)函数形式第一个参数是以字符串的形式传入的,这就为动态创建正则表达式提供了可能,在标题2中你可以领略到它的威力。
2)利用函数创建正则表达式的时候要注意一些字符的转义,比如\\d,以为我们并不是匹配一个\一个d,\d要用在一起表示匹配所有的数字,所以这里的\需要转义,转义的方式也很简单,就是加一个'\'
3)注意它们创建的方式。(2)函数中的第一个参数和(1)//里面的内容对应,第二个参数和g修饰符对应。

2.用正则实现lodash.js的_chunk函数

Example:

_.chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
 
_.chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]

_.chunk函数传入两个参数,根据第二个size把第一个参数数组切分。有没有觉得这个和1.面试题有点像呢?只不过这里size不一定是3.
传统的思考方法是:遍历这个数组,递增size,使用slice函数生成新的数组返回。

function chunk(array,size){
    const length = array.length;
    const block = Math.floor(length/size);
    console.log(block);
    const extra = length % size;
    const newArray = [];
    const index = 0;
    for(let i=1;i<=block;i++){
        newArray.push(array.slice((i-1)*size,i*size));
    }
    if(extra > 0){//处理末尾不足size的情况
        newArray.push(array.slice(-extra))
    }
    return newArray;
}

那么思考如何用正则来实现呢?根据1.的正则表达式你能试着写一下吗?
思考30秒~~~~~~~~~~~~~~~~~~~~~~~~~~~

其实答案很简单:

const chunk =(array,size) =>{
    const reg = new RegExp(`(\\w{${size}})(?=[^$])`,'g');
   return  array.join('').replace(reg,'$1-').split('-');
}

使用函数的方式创建正则表达式就可以实现。只不过这里使用的是w详相当于[0-9a-zA-Z].

源码上的处理兼容了多种可能。
下面附上库中源码:

function chunk(array, size) {
  size = Math.max(size, 0)
  const length = array == null ? 0 : array.length
  if (!length || size < 1) {
    return []
  }
  let index = 0
  let resIndex = 0
  const result = new Array(Math.ceil(length / size))

  while (index < length) {
    result[resIndex++] = slice(array, index, (index += size))
  }
  return result
}

3.开启真正的正则表达式

经过两个问题的引导,我们开始正式的正则表达式学习。
推荐几篇文章,大家可以先看一下了解正则表达式的基本知识。
参考链接:
全面讲解:https://segmentfault.com/a/11...

三 后记


specialcoder
2.2k 声望170 粉丝

前端 设计 摄影 文学