js replace 高級用法及適用場景


前言

近日刷編程題過程中發現善用 replace 及正則在處理數據時能做到極大的優雅簡潔,特此記錄分享一下。

replace 基本用法

語法: replace(regexp, string || function)
這里先介紹一下 replace 第二個參數可以傳入兩種類型:
1、字符串
  傳入字符串會將每次正則匹配到的結果替換為該字符串

let str = '我不是sb,你是sb嗎?';
// 第二個參數傳入字符串
str = str.replace(/sb/g, '**');
console.log(str); // 我不是**,你是**嗎?

2、回調函數
  傳入回調函數會將每次正則匹配到的結果替換為該函數的返回值

let str = '我不是sb,你是sb嗎?';
str = str.replace(/sb/g, () => '**');
console.log(str); // 我不是**,你是**嗎?

replace 高級用法

1、第二個參數傳入字符串時,可以在使用 $1-$9 獲取正則捕獲組的值,例如

let str = '我喜歡你';
str = str.replace(/(我喜歡)(你)/, '$1打完游戲再打$2');
console.log(str); // 我喜歡打完游戲再打你

適用場景

用於搜索結果關鍵字高亮顯示非常舒服:

let str = '你愛我,我愛你,蜜雪冰城甜蜜蜜';
let search = '蜜雪冰城';
str = str.replace(new RegExp(`(${search})`, 'g'), '<span style="color: red;">$1</span>');
console.log(str); // 你愛我,我愛你,<span style="color: red;">蜜雪冰城</span>甜蜜蜜

2、第二個參數傳入回調函數時,除了上述基本用法外,會在該回調函數調用時傳入參數,方便對數據進行處理

回調函數調用時第一個參數為當前匹配到的值,最后一個參數為當前匹配到的值的起始下標,若有使用正則捕獲組,則將$1-$9傳入第一個參數之后,最后一個參數仍然為當前匹配到的值的起始下標

適用場景

  • 模仿 Vue 數據綁定
let data = {
    name: '是明啊',
    hobby: ['打游戲', '編程'],
};
let str = '你好,我叫{{name}},我喜歡{{hobby.join("、")}}';
str = str.replace(/\{\{([\d\D]+?)\}\}/g, (v, k) => {
    with (data) {
        return eval(k);
    }
});
console.log(str); // 你好,我叫是明啊,我喜歡打游戲、編程
  • 英文首字母自動大寫
let str = 'I like play computer games and programming';
str = str.replace(/\s\w/g, v => v.toUpperCase());
console.log(str); // I Like Play Computer Games And Programming
  • 解析 url 參數
let url = 'https://www.baidu.com?user=admin&password=123#haha';
const params = {};
url.replace(/\??(\w+)=(\w+)&?/g, function (a, k, v) {
    params[k] = v;
});
console.log(params); // { user: 'admin', password: '123' }
  • 顏色格式轉換
function rgb2hex(sRGB) {
    if (!/^rgb\((\d{1,3},\s*){2}\d{1,3}\)$/.test(sRGB)) return '請輸入正確的rgb顏色代碼';
    let  color = '#';
    sRGB.replace(/\d+/g, n => color += ('0' + (+n).toString(16)).slice(-2));
    return color;
}
const color = rgb2hex('rgb(255, 100, 0)');
console.log(color); // #ff6400
  • css 樣式轉大駝峰
function cssStyle2DomStyle(sName) {
    return sName.replace(/-[a-z]/g, (v, i) => i===0?v.slice(-1):v.slice(-1).toUpperCase());
    // 這里就運用了形參最后一個參數:當前匹配到的值的起始下標,處理中划線前置問題
}
const style1 = cssStyle2DomStyle('border-radius');
const style2 = cssStyle2DomStyle('-webkit-border-image');
console.log(style1); // borderRadius
console.log(style2); // webkitBorderImage
  • 貨幣換算
let str = '一部手機2999人民幣,一件衣服200人民幣';
str = str.replace(/\d+人民幣/g, v => `${(v.slice(0, -3) * 0.1537).toFixed(2)}美元`);
console.log(str); // 一部手機460.95美元,一件衣服30.74美元
let str = '一部手機2999人民幣,一件衣服200人民幣';
str = str.replace(/(\d+)(人民幣)/g, (v, $1, $2) => `${($1 * 0.1537).toFixed(2)}美元(${$1}${$2})`);
console.log(str); // 一部手機460.95美元(2999人民幣),一件衣服30.74美元(200人民幣)
  • 時間顯示處理
function formatDate(t, str) {
    var obj = {
        yyyy: t.getFullYear(),
        yy: ('' + t.getFullYear()).slice(-2),
        M: t.getMonth() + 1,
        MM: ('0' + (t.getMonth() + 1)).slice(-2),
        d: t.getDate(),
        dd: ('0' + t.getDate()).slice(-2),
        H: t.getHours(),
        HH: ('0' + t.getHours()).slice(-2),
        h: t.getHours() % 12,
        hh: ('0' + t.getHours() % 12).slice(-2),
        m: t.getMinutes(),
        mm: ('0' + t.getMinutes()).slice(-2),
        s: t.getSeconds(),
        ss: ('0' + t.getSeconds()).slice(-2),
        w: ['日', '一', '二', '三', '四', '五', '六'][t.getDay()]
    };
    const reg = /y{2,4}|m{1,2}|d{1,2}|h{1,2}|s{1,2}|w/ig;
    return str.replace(reg, k => obj[k]);
}
const date1 = formatDate(new Date(1627430400000), 'yyyy-MM-dd HH:mm:ss 星期w');
const date2 = formatDate(new Date(1627430400000), 'yy-M-d H:m:s 星期w');
console.log(date1); // 2021-07-28 08:00:00 星期三
console.log(date2); // 21-7-28 8:0:0 星期三


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM