出來混總是要還的-JS正則前傳
阿新 • • 發佈:2018-11-11
前言: 正則表示式一直是個人痛點, 相信很多人 ( 說的就是你 ) 跟我一樣存在類似的情況, 正則是反覆學, 反覆忘, 從個人角度看主要的原因還是:較少的使用場景, 如果像陣列的幾個常用方法一樣, 絕大多數人肯定能熟練運用。 最近迫使我拿起正則這把屠龍刀的起因是( 時間充足和一道小的面試題 ), 那咱們就先從這道面試題說起
Demo1
// 觀察如下規律, 寫一個函式`accum`
// accum("abcd"); // "A-Bb-Ccc-Dddd"
// accum("helloWorld"); // "H-Ee-Lll-Llll-Ooooo-Wwwwww-Ooooooo-Rrrrrrrr-Lllllllll-Dddddddddd"
// accum("China"); // "C-Hh-Iii-Nnnn-Aaaaa"
複製程式碼
看到題的第一反應就是, 握草這還不簡單, 兩層迴圈加上珍藏多年的字串拼接技術(-_-||), 妥妥的解決這個問題
const accum = str => {
let result = "";
str.toLowerCase().split("").forEach((el, idx) => {
for (let i = 0; i <= idx; i++) {
if (i == 0) {
result += el.toUpperCase();
} else {
result += el;
}
}
result += el + "-";
});
return result.slice(0, -1);
// 看到slice慌不慌?是不是忘記這鬼東西是幹什麼的了?和substr/string有什麼區別?
};
console.log(accum("CHina"));
複製程式碼
寫完並且測試結果正確, 就開始沾沾自喜, 感覺萬事大吉。( 這種狀態很像在工作中, 寫完功能不去優化一樣 )
上面的一坨程式碼, 對, 就是一坨程式碼, 一坨像極了業務功能的邏輯程式碼, 沒有精巧的思路, 沒有精緻的寫法。 這踏馬跟鹹魚有什麼區別?
優雅的迴圈
const accum = str => {
let result = "";
for (let i = 0; i < str.length; i++) {
const temp = str[i];
result += temp.toUpperCase();
for (let j = i; j > 0; j--) {
result += temp.toLowerCase();
}
result += "-";
}
return result.slice(0, -1);
};
console.log(accum("CHina"));
複製程式碼
優雅的迴圈, 優雅的迴圈, 優雅的迴圈 啊、啊、啊!
精緻的利己主義者
const accum = str => {
return Array.from(str.toLowerCase(), (item, index) => {
return (
item.toUpperCase() + Array.from({length: index}, () => {
return item;
}
).join("")
);
}).join("-");
};
console.log(accum("CHina"));
複製程式碼
放蕩不羈的 reduce
const accum = str => {
return Array.from(str.toLowerCase()).reduce((accu, cur, idx) => {
accu.push(cur.toUpperCase().padEnd(idx + 1, cur));
return accu;
}, []).join("-");
};
console.log(accum("CHina"));
複製程式碼
百辟匕首( RegExp )
匹配與獲取字串方法
const accum = str => {
return str.toLowerCase().replace(/\w{1}/gi, (item, idx) => {
let temp = "";
Array.from(new Array(idx)).map(() => {
temp += item;
});
return `${item.toUpperCase()}${temp}-`;
}).slice(0, -1);
};
console.log(accum("CHina"));
複製程式碼
怎麼樣, 最後幾種方案看的是不是很刺激、很驚喜, 其實就是一堆奇葩操作, 這是
API
操作者的狂歡, 也是JS
開發者的基本功^_^
這幾個方案裡面最令人驚喜的還是 replace
, 當第二個引數是一個函式, 當第一個引數為正則表示式並且為全域性匹配模式時, 這個方法每次匹配都會被呼叫。
replace 應該是正則的 6 個常用 API 中最強大的一個, 它可以拿到你想要的資訊, 並且假借替換之名, 做一些神奇操作
傳送門 -> 正則操作的6個常用方法( 字串例項4個, 正則例項2個 )
注:
- \w 匹配單詞字元, 等價於[0-9a-ZA-Z_], 數字字母下劃線
- {1} 連續出現 1 次