正規表達式(或稱 Regex)是一連串的字元,我們可以用它來鎖定並操作字串中的特定元素。因此,我們可以:
💡 JavaScript 的正規表達式實作是 ECMA-262 語言標準的一部分,這表示你不必擔心瀏覽器之間的相容性問題。
在 JavaScript 中,正規表達式大多以/pattern/modifiers的格式撰寫。
建立正規表達式有兩種方式:
const regex = /[a-z]/;
const regex = new RegExp('[a-z]');
這兩種情況都會讓 JavaScript 從正規表達式建立一個物件。建議預設使用實字寫法,建立不可變的模式。
當正規表達式會變動,或是我們還不知道它的內容時(例如來自使用者的輸入),就可以使用RegExp建構函式。
正規表達式有一些選用的超能力,稱為flags,可以啟用額外的功能。
以下是幾個常見的:
/g - 全域搜尋/i - 忽略大小寫/m - 多行搜尋來看一個簡單的例子:
const re = /home/gi;
const str = 'Home, sweet home.';
const myArray = str.match(re);
console.log(myArray);
=> // ["Home", "home"]
g這個字元讓我們能解析字串中所有可能的匹配。如果沒有這個功能,JavaScript 只會擷取出第一個Home匹配。
忽略大小寫的/i旗標讓我們在尋找模式時更有彈性。這樣一來,我們要找的內容是大寫UPPERCASE還是小寫lowercase都無所謂。
使用RegExp建構函式時,加入旗標的語法不太一樣。
let regex = /[a-z]/gi; // literal notation
let regex = new RegExp('[a-z]', 'gi'); // constructor with string pattern as first argument
let regex = new RegExp(/[a-z]/, 'gi'); // constructor with regular expression literal as first argument (Starting with ECMAScript 6)
當正規表達式與 JavaScript 目前內建的函式結合時,我們就能用強大的方式操作字串並從中取得資料。
以下是幾個最常與正規表達式搭配使用的函式。
test()方法會搜尋正規表達式與指定字串之間的匹配。回傳 true 或 false。
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
使用match()方法時,我們會得到一個實用的陣列,它的內容取決於是否找到匹配。
這樣一來,我們就能從任何字串中搜尋並擷取資訊。例如:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;
funnyQuote.match(regex1);
// => ["someone", index: 11, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]
funnyQuote.match(regex2);
// => null
當帶有全域搜尋旗標/g時,這個方法不會只回傳唯一的匹配以及索引或輸入等實用資訊,而是回傳所有出現的結果並顯示在陣列中:
const funnyQuote =
'If you see someone crying, ask if it is because of their haircut.';
const regex3 = /if/gi;
funnyQuote.match(regex3);
// => ["If", "if"];
JavaScript 的replace()方法讓我們能在指定的字串中搜尋某個值,並將它替換成想要的新值。
string.replace(searchValue, newValue);
用來搜尋待替換內容的模式可以是單一字串,也可以是正規表達式。
let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');
let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');
此外,我們也可以在替換的位置套用函式,對每個值做額外的處理。
let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"
JavaScript 的split()方法則是用正規表達式來使用與操作字串的另一種方式。
這樣一來,我們會用正規表達式辨識某個模式,藉此分割指定的字串,例如str.split(/[,.\s]/)。這個模式會用作separator。
const str = 'hello,user.how are.you';
const result = str.split(/[,.\s]/);
console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']
你受雇於一家正在開發聊天機器人的公司,擔任正規表達式專家。
這個專案還在非常初階的開發階段,因此你的任務是運用正規表達式,提升聊天機器人理解與產生自然語言的能力。
聊天機器人不只聰明,還是個忠實的助手。
使用者想向聊天機器人提問,必須在指令的第一個位置說出「Chatbot」這個詞。
這個關鍵字是大寫還是小寫都無所謂,重要的是它出現的位置。
實作isValidCommand()函式,協助聊天機器人辨識使用者何時在下指令。
isValidCommand("Chatbot, play a song from the 80's.";
// => True
isValidCommand("Hey Chatbot, where is the closest pharmacy?";
// => False
isValidCommand("CHATBOT, do you have a solution for this challenge?";
// => True
聊天機器人很難理解人類如何用 emoji 表達情緒。
聊天機器人收到使用者的訊息時,每個 emoji 都會表示成「emoji」後面接著它的 id 編號。
實作removeEmoji()方法,接收一個字串,並移除整則訊息中所有 emoji 的加密。
不含 emoji 文字的行,應該原封不動地回傳。
只要移除 emoji 字串就好,不要試著調整空白。
針對這個挑戰,請使用建構函式語法來建立正規表達式。
removeEmoji("I love playing videogames emoji3465 it's one of my hobbies");
// => "I love playing videogames it's one of my hobbies"
考量到使用者會從行動應用程式下載聊天機器人的功能,他們在對話過程中需要輸入手機號碼。
問題在於,聊天機器人只能讀取並驗證特定格式的號碼。
如果號碼有效(符合正規表達式指定的字元序列),聊天機器人會回覆一則訊息,感謝使用者並確認號碼。如果號碼無效,函式會告知使用者這個電話號碼不正確。
預期的格式是:(+##) ###-###-###
checkPhoneNumber('(+34) 659-771-594');
// => "Thanks! You can now download me to your phone."
checkPhoneNumber('659-771-594');
// => "Oops, it seems like I can't reach out to 659-771-594"
聊天機器人是非常好奇的軟體。雖然它能在網路上搜尋特定主題,但它喜歡詢問使用者有沒有很酷的網站或 URL,好去找到相關資訊。
對話範例:
實作getURL()函式,它能回傳一個只包含各個網站連結的陣列。要寫出能辨識任何 URL 的正規表達式會非常複雜,但聊天機器人只需要讀取簡單的 URL。在這個練習中,URL 就是任何以"."分隔的字詞序列。
getURL(
'I learned a lot from exercism.org and developer.mozilla.org, but I found ts39.es very boring!',
);
// => ["exercism.org", "developer.mozilla.org", "ts39.es"];
為了儲存所有與它對話過的人員資料,聊天機器人能從使用者的個人檔案中,以下面這種格式取得全名:「smith, john」。
這麼一來,我們希望聊天機器人非常有禮貌,並留下良好的印象。
撰寫niceToMeetYou()函式,它接收一個包含使用者全名的字串,並回傳字串**「Nice to meet you, John Smith」**。
為了學習的目的,請使用正規表達式中的取代方法來實作這個函式。
let str = 'Smith, John';
niceToMeetYou(str);
// => "Nice to meet you, John Smith"