這是一篇普通的教程,同時也是我的一篇筆記。起因是看到一道題目的另外一種解法特别有意思,同時也做一點正則的筆記,好了解。
題目
我印象中的這道題目是:
有一組數組為
[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的正則比對