【面試題】我花了6個回合才解決,你呢?

昨天,女友的同事在他們羣裏討論一個面試題,題目是這樣嬸兒的:輸入 get1_install2_app3_list4_by5_android6 , 每一個單詞後面總會攜帶一個數字,只有偶數才刪掉,在不使用循環控制語句,只用正則表達式,實現輸出 get1InstallApp3ListBy5Androidandroid

ok, 廢話很少說直接開幹:面試

round one

首先,觀察輸入,發現規律是這樣的 英文 + 數字 + _ ,而後,不能有偶數因而,天然而然有如下正則:正則表達式

/[a-z]+[13579]+/gisegmentfault

var str = 'get1_install2_app3_list4_by5_android6';

str.match(/[a-z]+[13579]+/gi)
// ["get1", "app3", "by5"]

發現,偶數前的英文掉了,因而,有了下面:數組

/[a-z]+[13579]+_[a-z]+/giapp

str.match(/[a-z]+[13579]+_[a-z]+/gi);
// ["get1_install", "app3_list", "by5_android"]

剩下就是把 _ 替換掉,就能夠了code

str.match(/[a-z]+[13579]+_[a-z]+/gi).join('').replace(/_/g,'')
// get1installapp3listby5android

貌似,是能夠了,可是,若是three

var str = 'get1_install2_app3_list4_by5_android6_demo7';
str.match(/[a-z]+[13579]+_[a-z]+/gi);
// ["get1_install", "app3_list", "by5_android"]

發現 demo7 不見了。negative字符串

round two

上面的正則,在有奇數個 英文 + 數字 時候,會漏掉最後一個,由於,咱們的正則 是 英文 + 數字 + ’英文‘,demo7英文 + 數字,因此不匹配。因而,再加上這個不就能夠了嗎,因而有了:get

/[a-z]+[13579]+_[a-z]+|[a-z]+[13579]+/gi

var str = 'get1_install2_app3_list4_by5_android6_demo7';
str.match(/[a-z]+[13579]+_[a-z]+|[a-z]+[13579]+/gi)
// ["get1_install", "app3_list", "by5_android", "demo7"]

貌似,是能夠了,可是,若是

str 不是 嚴格的 英文_奇數_英文_偶數_... 這樣的規律,而是 英文_偶數_英文_奇數...,就不行了,好比:

var str = 'get0_install1_app2_list3_by4_android5_demo6';
str.match(/[a-z]+[13579]+_[a-z]+|[a-z]+[13579]+/gi)
// ["install1_app", "list3_by", "android5_demo"]

發現 get 不見了。negative

round three

發現,思路錯了,既然要求是須要刪掉 偶數,爲啥不從 偶數 出發,匹配 非偶數

/[^02468]+/gi

var str = 'get0_install1_app2_list3_by4_android5_demo6';
str.match(/[^02468]+/gi);
// ["get", "_install1_app", "_list3_by", "_android5_demo"]

貌似,是能夠了,可是,仔細觀察輸出,

發現,人家還有 小駝峯命名, negative

round four

上一步中,已經 獲得 相似這樣的數組:["get", "_install1_app", "_list3_by", "_android5_demo"]

只需將 _字符 替換爲 大寫,便可:

var str = 'get0_install1_app2_list3_by4_android5_demo6';
str.match(/[^02468]+/gi).join('').replace(/_\w/g, function(word) {
  return word.substring(1).toUpperCase();
});
// getInstall1AppList3ByAndroid5Demo

歐耶,終於,符合要求了 victory

這個解法有問題 round six 有解釋

round five

如今回過頭想一想,發現,根本不須要那麼多過程。從一開始的思路錯誤,到後來的思路調整,最後,得出答案,可是,若是,咱們換一種思路,從新思考這道題:

輸入get1_install2_app3_list4_by5_android6

輸出get1InstallApp3ListBy5Android

特色:偶數去掉了;小駝峯命名;

因而 有了:

var str = "get1_install2_app3_list4_by5_android6";
str.replace(/[02468]+/g, '').replace(/_\w/g, function(word) {
  return word.substring(1).toUpperCase();
});

因此,要善於審題(0_0),找出最核心要求,Give me five

這個解法有問題 round six 有解釋

round six

很是感謝 @老鼠擰刀滿街找貓,發現了這個解法的問題,謝謝!!!

就是偶數的正則匹配存在問題,當出現 a12a122結果就是錯的,因此修改以下:

var str = "one1_two2_three3_four4_five5_six6_seven7_eight8_nine9_ten10_eleven11_twelve12_a123_b122_c1223";

str
.replace(/\d+/g, function(num) {
  return num % 2 ? num : '';
})
.replace(/_\w/g, function(word) {
  return word.substring(1).toUpperCase();
});
// one1TwoThree3FourFive5SixSeven7EightNine9TenEleven11TwelveA123BC1223

但願此次沒啥大問題,尷尬0_0!

答案是什麼,已經特別重要,重要的是思想的過程。記錄下,我是怎麼一步一步試錯知足要求的。若是你有更好的解法,歡迎評論去留言。

知識點

最後,列下用到了正則的哪些知識點。

  • [abc] 查找方括號之間的任何字符
  • [a-z] 查找任何從 a 至 z 的字符
  • n+ 匹配任何包含至少一個 n 的字符串
  • [^xyz] 不匹配這個集合中的任何一個字符
  • \w 匹配字母或數字或下劃線或漢字 等價於 '[^A-Za-z0-9_]'
相關文章
相關標籤/搜索