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

## 面試題html

校驗用戶名錶單,長度爲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 正則書籍

  • 基礎正則表達式

    • 學習正則表達式
    • 正則表達式必知必會
    • 神奇的匹配
  • 進階express

    • 精通正則表達式
    • 正則指引

3.2 正則工具

相關文章
相關標籤/搜索