从一道JavaScript问题学点正则

这是一篇平常的教程,同时也是我的一篇笔记。原由是看到一道问题的别的一种解法迥殊有意思,同时也做一点正则的笔记,好明白。

问题

我印象中的这道问题是:
有一组数组为[1,1,2,3,3,3,3,4,5,5,5,6,6]
运用js
把它变成[[1,1],2,[3,3,3],4,[5,5,5].[6,6]]

解法有许多,我这里只列出两种

解法一

我们日常平凡的解法平常为:
数组嵌套,将含有雷同的值得数组放入新数组内里
然后对新数组举行,对内里的嵌套数组举行个数推断并返回值,从新构成一个新数组
新数组就是答案

var arr = [1,1,2,3,3,3,3,4,5,5,5,6,6];
var tempArr = [];
var result = [];
var i,len,item,lastArr;

for(i = 0,len = arr.length;i < len;i++){
    item = arr[i];
    lastArr = tempArr.slice(-1)[0];

    if(!lastArr || lastArr[0] != item){
        lastArr = [];
        tempArr.push(lastArr);
    }

    lastArr.push(item);
}

for(i=0,len=tempArr.length;i<len;i++){
    item = tempArr[i];
    result.push(item.length > 1 ? item : item[0]);
}

console.log(result);

解法二

假如我们用正则的话,那解法以下:

var arr = [1,1,2,3,3,3,3,4,5,5,5,6,6];

var result = "[" +
    (arr.toString() + ",")
        .replace(/(([^,]+,)\2+)/g,'[$1],')
        .replace(/,(]|$)/g,'$1')
    + "]";

console.log(JSON.parse(result));

如许一会儿就变得很高效,正则找出两个以上的雷同值的位置,插进去[]
然后打印出来即可。

从这段代码,我们能够看出,
先对把数组字符串化

var result = "[" +
    (arr.toString() + ",")
    + "]";

变成[1,1,2,3,3,3,3,4,5,5,5,6,6,]

然后婚配两个以互为雷同的值,套上[]

var result = "[" +
    (arr.toString() + ",")
        .replace(/(([^,]+,)\2+)/g,'[$1],')
    + "]";

末了是找到]前面过剩的,

var result = "[" +
    (arr.toString() + ",")
        .replace(/(([^,]+,)\2+)/g,'[$1],')
        .replace(/,(]|$)/g,'$1')
    + "]";

JSON.parse(result)转为数组对象,打印即可

正则表达式

经由过程解法二,我们有时候面临一些问题,实在另有更简朴的解决方法

下面再补充一下正则的知识点

元字符

.replace(/((\[^,]+,)\2+)/g,'[$1],')中,正则部份是/((\[^,]+,)\2+)/g

个中最前面的“/”与末了面的“/”是分隔符,示意正则表达式的最先与完毕.

这里再补充元字符的申明

代码寄义
.婚配除换行符之外的恣意字符
\w婚配字母或数字或下划线或汉字
\W婚配恣意不是字母或数字或下划线或汉字的字符
\s婚配恣意的空白符
\S婚配恣意非空白符
\d婚配数字
\D婚配非数字
\b婚配单词的最先或完毕
^婚配字符串的最先
$婚配字符串的完毕

标志

末了的“g”标志示意正则表达式运用的global(全局)的状况.运用 global 标志表明在被查找的字符串中搜刮操纵将查找一切相符的项,而不仅仅是第一个.这也被称为全局婚配.【相干的标志另有i(ignoreCase,示意疏忽大小写)、m(multiline,示意许可跨行)】,以下表所示

补充一下标志

标志形貌
g全局搜刮
i不辨别大小写搜刮
m多行搜刮
y实行“粘性”搜刮,婚配从目的字符串的当前位置最先,能够运用y标志

限定符

然后我们再来看中心的主体部份((\[^,]+,)\2+)

字符组就是在[](方括号)中列举出一切的能够再去婚配,+是指婚配前面一个表达式1次或许屡次,

补充一下限定符

代码寄义
*复零次或更屡次
+反复一次或更屡次
?反复零次或一次
{n}反复n次
{n,}反复n次或更屡次
{n,m}反复n到m次

.replace(/((\[^,]+,)\2+)/g,'[$1],')中的$1婚配到的部份的替代,替代成[$1],

婚配的部份,值得是两个以上雷同的值

.replace(/,(]|$)/g,'$1')就是去,]里的,

写得好乱···

我这篇文章也用到了对URL的正则婚配

    原文作者:Chakhsu
    原文地址: https://segmentfault.com/a/1190000008398687
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞