出處: https://www.hackerrank.com/challenges/js10-regexp-2/problem?isFullScreen=true
這題也是驗證文字格式,規則如下:
- 文字開頭是一個簡稱像是
Mr.
,Mrs.
,Ms.
,Dr.
, orEr.
- 在簡稱之後,會是一個或多個英文字,且大小寫都有可能。
以下是它給的幾個範例:
Mr.X => true
Mrs.Y => true
Dr#Joseph => false
Er .Abc => false
先做過 解題 38. HackerRank > 10 Days of Javascript > Day 7: Regular Expressions I (表準表達式的 test) 後,這題可以說毫無難度可言。
一樣先從開頭做起。
第一個字大寫,後面接 1~n 個小寫字,然後加一個 “ . ”。
這邊值得注意的一點 「 . 」是 Regular Expressions 的保留字符,代表除了換行以外的任一字元,為了能夠正確地被當成 「 . 」 來看待,前面必須加一個 「 \ 」。
const re = /^[A-Z][a-z]+\./ re.test("Mr.X") // return true re.test("Mrs.Y") // return true re.test("Dr#Joseph") // return false re.test("Er .Abc") // return false re.test("Er.Dr.") // return true // 如果沒有在 . 的前面加 \ ,除了換行以外的字元都會被匹配 const re_2 = /^[A-Z][a-z]+./ re_2.test("Mr.X") // return true re_2.test("Mrs.Y") // return true re_2.test("Dr#Joseph") // return true re_2.test("Er .Abc") // return true re_2.test("Er.Dr.") // return true
驗證中間到結尾的文字。
規則:不能有空格,大小寫英文,長度是 1 ~ n 個, 然後結束。以下就是正確的答案。
const re = /^[A-Z][a-z]+\.[a-zA-Z]+$/ re.test("Mr.X") // return true re.test("Mrs.Y") // return true re.test("Dr#Joseph") // return false re.test("Er .Abc") // return false re.test("Er.Dr.") // return false
簡寫
Regular Expressions 把常用的規則,變成簡寫,我個人覺得可以背下來的:
簡寫 | 意義 |
\d | 吻合數字,寫法等同於 [0-9] 。 |
\D | 吻合非數字,寫法等同於 [^0-9]。 |
包含數字字母與底線,等同於[A-Za-z0-9_] | |
\W | 數字字母與底線以外的字,等同於[^A-Za-z0-9_] |
\s | 各種空白字符 |
\S | 各種非空白字符 |
常用的排除做法,例如我想要所有的大小寫字母包含底線,不包含數字
[^\d\W] 是一個非常好用的做法。
const re = /^[^\d\W]+$/ re.test("abc") // return true re.test("abc1") // return false
如果是所有的大小寫字母但排除 “A” 和 “a”。則可以寫成以下:
const re = /^[^aA\W]+$/ re.test("abc") // return true re.test("abc1") // return false re.test("bcd") // return true re.test("bcd1") // return true
回到原本的題目,如果用簡寫,可以寫成以下:
可以發現其實如果要排除,用簡寫也沒有好寫多少。
const re = /^[A-Z][a-z]+\.[^\_\d\W]+$/ re.test("Mr.X") // return true re.test("Mrs.Y") // return true re.test("Dr#Joseph") // return false re.test("Er .Abc") // return false re.test("Er.Dr.") // return false
衍伸題目
驗證 Email
- 開頭是 1- n 個英文數字或底線 => ^\w+
- 中間出現 0 – n 個「 – 」或 「 . 」但必須接英文數字或底線 => ((-\w+)|(\.\w+))*
- 接 @ => @
- @ 後面一定要接 1 ~ n 個英文, 數字 => [a-zA-Z0-9]+ 或用排除法 [^\d\.\_\W]+
- 英文後後面可能是 0 ~ n 個 「 – 」或 「 . 」加英文或數字, 但不能連續出現 => ((-\w+)|(\.\w+))*
- 結尾必須是 「 . 」和 1 ~ n 個英文 => \.[a-zA-Z]+$
const re = /^\w+((-\w+)|(\.\w+))*@[^\d\.\_\W]+((-\w+)|(\.\w+))*\.[a-zA-Z]+$/ re.test("[email protected]") // return true re.test("[email protected]") // return true re.test("[email protected]") // return true re.test("[email protected]") // return false re.test("test-1.com.tw") // return false
驗證手機號碼
- 09 開頭或 +8869 開頭 => ^(09|\+8869)
- 8 碼數字並結束 => [0-9]{8}$
const re = /^(09|\+8869)[0-9]{8}$/ re.test("0912345678") // return true re.test("+886912345678") // return true // 或是簡寫 const re_2 = /^09[\d]{8}$/ re_2.test("0912345678") // return true re_2.test("+886912345678") // return true