banner
他山之石

他山之石

關於一道字符串格式化面試題的思考


本文從一道簡單的字符串面試題開始,記錄字符串的一些方法,關注細節。

image

最近遇到一道面試題,覺得挺有意思,雖然簡單卻發人深省。題目大致如下:寫一個字符串轉成駝峰的方法,例.bottom.color->borderBottomColor。

操作字符串數組#

大部分人應該都能寫出這種方法,對字符串進行處理然後拼接成新的字符串。主要考察字符串的幾個 API,使用 charAt (n) 來取得字符串第 n 個下標的字符,也可以使用數組下標 ([]) 來取。

function tranformStr(str) {
  var strArr = str.split(".");
  for (var i = 1; i < strArr.length; i++) {
    strArr[i] = strArr[i].charAt(0).toUpperCase() + strArr[i].substring(1);
  }
  return strArr.join("");
}

正則表達式#

第二種使用正則來解決,其實算是字符串的 replace 方法和正則的結合,難點主要還是在於 replace 方法的掌握。

function transformStr(str) {
  var re = /\.(\w)/g;
  return str.replace(re, function(match, p1) {
    return p1.toUpperCase();
  });
}

從以上兩種方法可以看出,使用正則的代碼量更少,但是對正則的理解和 replace 用法的要求也更高,下面總結一下 replace 這個字符串方法的一些 api。

replace 使用#

str.replace(regexp|substr, newSubStr|function)

replace 方法的第一個參數可以是一個正則或者字符串。

  • regexp (pattern)

一個正則表達式(RegExp) 對象或者其字面量。該正則所匹配的內容會被第二個參數的返回值替換掉。

  • substr (pattern)

一個要被 newSubStr 替換的字符串。其被視為一整個字符串,而不是一個正則表達式。僅僅是第一個匹配會被替換。

replace 方法的第二個參數可以是一個字符串或者函數。

  • newSubStr (replacement)

用於替換掉第一個參數在原字符串中的匹配部分的字符串。該字符串中可以內插一些特殊的變量名。參考下面的使用字符串作為參數。

  • function (replacement)

一個用來創建新子字符串的函數,該函數的返回值將替換掉第一個參數匹配到的結果。參考下面的指定一個函數作為參數。

replace 方法並不改變調用它的字符串本身,而只是返回一個新的替換後的字符串。
在進行全局的搜索替換時,正則表達式需包含 g 標誌。

使用字符串作為參數#

當第二個參數是字符串時,替換字符串可以插入下面的特殊變量名:

變量名代表的值
$$插入一個 "$"。
$&插入匹配的子串。
$`插入當前匹配的子串左邊的內容。
$'插入當前匹配的子串右邊的內容。
$n假如第一個參數是 RegExp 對象,並且 n 是個小於 100 的非負整數,那麼插入第 n 個括號匹配的字符串。

下面是特殊變量名的具體使用:

"border.bottom.color".replace(/\.(\w)/g, "$$");
// border$ottom$olor
"border.bottom.color".replace(/\.(\w)/g, "$&");
// border.bottom.color
"border.bottom.color".replace(/\.(\w)/g, "$`");
// borderborderottomborder.bottomolor
"border.bottom.color".replace(/\.(\w)/g, "$1");
// borderbottomcolor

指定一個函數作為參數#

當第二個參數是一個函數時,在這種情況下,當匹配執行後, 该函數就會執行。 函數的返回值作為替換字符串。 (注意:上面提到的特殊替換參數在這裡不能被使用。) 另外要注意的是, 如果第一個參數是正則表達式, 並且其為全局匹配模式, 那麼這個方法將被多次調用, 每次匹配都會被調用。

變量名代表的值
match匹配的子串。(對應於上述的 $&。)
p1,p2, ...假如 replace () 方法的第一個參數是一個 RegExp 對象,則代表第 n 個括號匹配的字符串。(對應於上述的 $1,$2 等。)
offset匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 “abcd”,匹配到的子字符串是 “bc”,那麼這個參數將是 1)
string被匹配的原字符串。

注意:精確的參數個數依賴於 replace () 的第一個參數是否是一個正則表達式對象, 以及這個正則表達式中指定了多少個括號子串。

在文章最開始的題目中,我們需要匹配。後面跟著的第一個字母,並且將其替換為大寫字母。具體實現代碼如下:

function transformStr(str) {
  var re = /\.(\w)/g;
  return str.replace(re, function(match, p1) {
    return p1.toUpperCase();
  });
}

首先,聲明一個正則 re,匹配一個。後面跟著一個括號,這個括號稱為捕獲括號,匹配的內容會被記住以供第二個參數使用,捕獲括號內的 \w 匹配一個單字字符(字母、數字或者下劃線),等價於 [A-Za-z0-9]。第二個參數為函數,第一個字符串 match 是每次匹配到的字符串,在上述例子中就是.b 和.c,p1 則對應第一個括號匹配的字符串,對應 b 和 c,在函數內部對 p1 進行大寫轉換,因為 replace 產生的是一個全新的字符串,所以需要 return 出去。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。