當我問表單校驗的面試題時,我期望得到什麼樣的答案

41202197514發表於2018-03-04

面試題

校驗使用者名稱錶單,長度為8-10位的只包含數字和字母的字串,用JavaScript實現一個校驗函式。

1 解決過程

1.1 首先確認題目需求(幾乎沒有人確認過,當然也沒有人寫對過)

1.1.1 題目要求

  • 長度8-10位

  • 只包含數字和字母

  • JS校驗函式

1.1.2 Tips

  • 幾乎沒人確認過

  • 沒人寫對過

  • 如果這裡有問題,後面肯定對不了

1.2 其次分析思路(轉換為可以寫程式碼的等價邏輯表達,也沒人寫對過)

1.2.1 等價邏輯轉換一

  • 包含字母

  • 包含數字

  • 只能是數字和字母

  • 長度8-10位

1.2.2 等價邏輯轉換二

  • 不 全為數字

  • 不 全為字母

  • 只能是數字和字母

  • 長度8-10位

1.2.3 等價邏輯轉換三

  • 所有字元ASCII碼在數字和字母的範圍內

  • 長度8-10位

1.2.4 Tips

  • 即使前面需求理解清楚,這裡轉換不等價也得不到正確的結果

  • 有了這裡面的等價分解,最基本的TestCase也就有了,便於後面做校驗

  • 即使寫不出程式碼來,這裡能說清楚也行

  • 說不清楚也行,需要能看到不斷嘗試,積極思考的過程

1.3 然後是核心程式碼實現(清一色的正則,我們也先說正則)

1.3.1 使用零寬正向先行斷言

1.3.1.1 程式碼實現
 /^(?=.*\d.*)(?=.*[a-zA-Z].*)[0-9a-zA-Z]{8,10}$/.test(str)

1.3.1.2 程式碼解釋
  • (?=)表達正向先行斷言,滿足條件的其他匹配結果才為真,即括號內的表示式匹配整個匹配結果才為真

  • 可以出現在程式碼的任意位置

  • 不佔用最終的匹配寬度

  • 這裡表達既包含數字又包含字母的只包含數字和字母的8-10位的字串

1.3.1.3 邏輯表達
  • 包含數字

  • 包含字母

  • 8-10位的數字和字母的組合(全匹配)

1.3.2 使用零寬負向先行斷言

1.3.2.1 程式碼實現
 /^(?!\d+$)(?![a-zA-Z]+$)[0-9a-zA-Z]{8,10}$/.test(str)

1.3.2.2 程式碼解釋
  • (?!) 表達負向先行斷言,滿足非條件的其他匹配結果才為真,即括號內的表示式不匹配整個匹配結果才為真

  • 可以出現在程式碼的任意位置

  • 不佔用最終的匹配寬度

  • 這裡表達不全為數字且不全為字母的只包含數字和字母的8-10位的字串

1.3.2.3 邏輯表達
  • 不全為數字的(全匹配)

  • 不全為字母的(全匹配)

  • 8-10位的數字和字母的組合(全匹配)

1.3.2.4

1.3.3 如果不知道上面的方式,可以拆分一下

1.3.3.1 程式碼實現
 !/^\d+$/.test(str) && !/^[a-zA-Z]+$/.test(str) && /^[0-9a-zA-Z]{8,10}$/.test(str)

1.3.3.2 程式碼解釋
  • 不解釋了,直接的邏輯表達

1.3.3.3 邏輯表達
  • 不全為數字的(全匹配)

  • 不全為字母的(全匹配)

  • 8-10位的數字和字母的組合(全匹配)

1.3.4 如果不知道正則怎麼玩,也可以用字元判斷的方式

1.3.4.1 程式碼實現
 //考慮記不住ASCII碼 var rangeChars = '09azAZ'; var char0Code = rangeChars.charCodeAt(0), char9Code = rangeChars.charCodeAt(1), charaCode = rangeChars.charCodeAt(2), charzCode = rangeChars.charCodeAt(3), charACode = rangeChars.charCodeAt(4), charZCode = rangeChars.charCodeAt(5);  Array.from(str).every(char => {  return '0' <= char && char <= '9' || 'a' <= char && char <= 'z' || 'A' <= char && char <= 'Z'  });  Array.from(str).some(char => {     return '0' <= char && char <= '9' });  Array.from(str).some(char => {  return 'a' <= char && char <= 'z' || 'A' <= char && char <= 'Z'  });  8 <= str.length && str.length <= 10

1.4 最後是結果的輸出

 export const validationUtil = {     isNameValid:(str) => {         //呼叫isNameValid 的同時,不應該有判斷undefind,判斷null的過程,表單取出來的不會有這倆值         str += '';         str = str.trim();         return /^(?!\d+$)(?![a-zA-Z]+$)[0-9a-zA-Z]{8,10}$/.test(str);     } }

2 常見問題

  • 校驗不寫trim

  • 正則不寫首尾匹配

  • /^[0-9a-zA-Z]{8,10}$/ 作為題目結果

  • 自己寫出來的正則,自己也不知道啥意思

3 參考資料

3.1 正則書籍

  • 基礎

    • 學習正規表示式

    • 正規表示式必知必會

    • 神奇的匹配

  • 進階

    • 精通正規表示式

    • 正則指引

3.2 正則工具

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/20597700/viewspace-2151490/,如需轉載,請註明出處,否則將追究法律責任。

相關文章