5 kyu
將字串結尾的數字部分遞增,若不是數字則加上一個 1。
並且維持數字的字元數量,例如:012 → 013。
使用正則表達式,將字串拆成兩段;
前面可能有字串或數字,但結尾必須只有數字。
捕獲數字的部分,如果字尾獲取不到,就直接+1。
利用字串長度,確保遞增後的數字長度與原本相同。
let reg = /^(...)(...)$/
let result = str.match(reg)
if(!result) return str + "1"
return result[1] + (result[2]+1)
function incrementString(strng) {
let regExp = /^(.*?)(\d+)$/;
let result = strng.match(regExp);
if (!result) return strng + "1";
let number = +result[2] + 1;
return result[1] + "0".repeat(Math.max(result[2].length - String(number).length, 0)) + number;
}
使用 ()
可個別捕獲不同的正則條件,match 利用匹配的結果建立陣列。
/^(.*?)(\d+)$/
(.*?)
表示匹配任意數量的字元,但以後面的捕獲分組為主。
.
表示單一字元;*
表示零到多次;? 表示零或一,在這裡為表示匹配較少。foobar00999
為例,若第一捕獲有 ?
限制:["foobar00999", "foobar", "00999"]
。?
限制:["foobar00999", "foobar0099", "9"]
。(\d+)
表示匹配一到多次的數字。match 返回的結果,將數字的部分 +1。
原始匹配的長度、扣掉轉換成數字並遞增後的長度,Math.max
與 0 取最大值(因為可能有負數),得到 repeat 計算需要補的 0 的次數;最後跟第一捕獲組拼接出結果。
let incrementString = str => str.replace(/([0-8]|\d?9+)?$/, (e) => e ? + e + 1 : 1)
直接使用 replace 方法,會返回處理後的字串。
正則表達式可多次拆分來看:
(…)?$
表示符合 ()
捕獲條件零或一次,$
表示這個捕獲在字串結尾。
裡面的條件 [0-8]|\d?9+
可能有兩種情況;結尾數字由 0-8 組成,或者最後位為 9,一次或多次的 9,且前面拼接一個或零個數字 0-9。
這個做法用意是分為要進位,以及不用進位兩種狀況;如果不需進位就獲取最後尾一個數字。
如果需要進位,則獲取字尾數來的連續的 9,以及它前面的數字。
符合條件一:foobar000
,只捕獲最後一個 0
。
符合條件二:foobar00999
,捕獲 0999
。
第二參數的三元運算子,如果符合條件則將 match 的內容轉為數字後+1,若不符合條件則表示沒有數字做為結尾,則返回 1。
如果要問我自學過程中,理解哪些知識點時最讓我煎熬?
我第一個想到遞迴、第二大概就是正則表達式。
(不過自從學了 Functional Programming,又再加上 Functional Programming🫠)
不過,越是解題就越是感受到正則的強大,
搭配一些簡單的方法就能辦到很多事、解決很多問題。
有機會一定要找一下訓練寫正則條件的平台‼️