學習軌道
/
JavaScript
JavaScript
/
練習
/
正規聊天機器人
正規聊天機器人

正規聊天機器人

學習練習

簡介

JavaScript 中的正規表達式

正規表達式(或稱 Regex)是一連串的字元,我們可以用它來鎖定並操作字串中的特定元素。因此,我們可以:

  • 在字串中搜尋文字
  • 取代字串中的子字串
  • 從字串中擷取資訊

💡 JavaScript 的正規表達式實作是 ECMA-262 語言標準的一部分,這表示你不必擔心瀏覽器之間的相容性問題。

如何建立正規表達式

在 JavaScript 中,正規表達式大多以/pattern/modifiers的格式撰寫。

建立正規表達式有兩種方式:

  1. 正規表達式實字:
const regex = /[a-z]/;
  1. RegExp建構函式:
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

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

使用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"];

Replace

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"

Split

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 都會表示成「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,好去找到相關資訊。

對話範例:

  • 聊天機器人:嘿 username,我想學怎麼用 JavaScript 寫程式,你知道有什麼很酷的網站可以讓我學習嗎?
  • 使用者:我從 exercism.org 學到很多。

實作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"
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
JavaScript Exercism

準備好開始 正規聊天機器人 了嗎?

註冊 Exercism,透過 37 個概念159 個練習 和真人引導來學習並精通 JavaScript,全部免費。