深入探索 JavaScript 中的 RegExp:創建動態規則運算式

更新日期: 2024 年 3 月 14 日

JavaScript 的 new RegExp 功能允許開發者在程式運行時,才決定如何搜尋或匹配文本。

特別適合於當你事前不確定要搜尋的文本內容,或需要根據使用者的輸入,來確定搜尋條件的情況。

簡單來說,就是可以讓你根據實際需要,隨時自定義搜尋規則。

new RegExp 的語法

new RegExp 方法接受兩個參數:pattern(模式) 與 flags(修飾符)。

其基本語法如下:

let regex = new RegExp(pattern, flags);

pattern(模式)

當你用 new RegExp 創建規則運算式時,「pattern(模式)」就像是你給搜尋引擎的一張搜尋清單,告訴它你想找的文字長什麼樣子。

這個模式可以是具體的文字,比如你告訴它我要找「貓」,也可以是比較含糊的指令,比如找所有的電話號碼或電子郵件地址。

想像一下,你在一本書里找某個詞,「pattern」就是那個詞。

但是,規則運算式的厲害之處在於,它可以不只找一個確切的詞,還可以根據你定義的模式找到一系列符合某種特徵的文字。

比如,你可以告訴它,我要找所有以「貓」開頭,後面跟著三個字的詞,或者找所有的「貓」和「狗」。

在這個「pattern」裡面,你可以用一些特殊的符號來幫助描述你想找的東西。例如:

直接字符

就是直接告訴搜尋引擎你要找的字,比如你告訴它我要找「apple」,那它就會去找所有「apple」的字眼。

特殊字符

這些是一些有特殊意涵的符號,它們可以幫你找到更多不同的東西。比如:

  • . 符號:可以代表任何一個字母或數字,想象一下你在問:「有沒有任何字母或數字在這裡?」
  • * 符號:是用來找某個東西出現了多次的,甚至是零次,好像在說:「這個東西可能一次都沒有,也可能一堆。」
  • + 符號:則是至少要有一次,就是:「這個東西至少要出現一次,多了也沒關係。」

字符類

這個像是你給搜尋引擎一個選擇題,比如[abc]就是說:我要找「a」、「b」、或者「c」,三選一。

量詞

這個可以指定你要找的東西出現的次數,像是{2,3}就是在問:這個東西出現 2 次或 3 次的有嗎?

位置匹配

有時候你對在哪裡找到的東西很在意,比如:

  • ^ 符號:是說我只在乎開頭的部分,如果開頭符合我就要。
  • $ 符號:則是我只在乎結尾的部分,結尾對了就行。

用這些技巧,你可以讓規則運算式變成一個超級精確的搜尋工具,幫你找到需要的任何文字信息。

flags(修飾符)

當你用 new RegExp 來創建規則運算式時,除了告訴它要找的模式外,你還可以選擇加一些特別的「提示」來幫助它更好地找到你要的東西,這就是所謂的「flags(修飾符)」。

這些「提示」可以讓搜尋變得更靈活,以下是幾個常見的提示:

  • g:通常,找到一個符合條件的就會停止搜尋。加上這個 g,就像是告訴它「全場都搜一遍,找到所有符合的地方」。
  • i:有時候我們不在乎大小寫,比如「Apple」和「apple」對我們來說是一樣的。這時候加上「i」,就是告訴它大寫、小寫都一視同仁,你不用區分。
  • s:通常情況下,.(點)這個特殊字符用於匹配除換行符(\n)之外的任意單個字符。但有時候,我們希望連換行符也包括在內,使得.能匹配任何字符,包括換行符。
  • m:如果你的文字是分成多行的,通常情況下搜尋是看成一整塊文字的。加上 m,就像是告訴它「每一行都是獨立的,分開來看」。
  • u:有時候文字中會有特殊的國際字元或表情符號,用 u 就是告訴它這些特殊的字元也要正確處理。
  • y:這個有點像是遊戲中的「必須從這裡開始」的限制。加上 y,就是告訴它「你只能從我指定的地方開始找,不能隨便找」。

這些「提示」就像是給搜尋引擎的便利貼,幫助它更好地按照你的要求去找資料。根據你想要如何搜尋,選擇合適的修飾符,就能讓你的搜尋更加精準。

回傳值

使用 new RegExp 會返回一個規則運算式物件。

這個物件裡面包含了你設定的搜尋模式(也就是你想要搜尋的規則,比如某個詞或者字符序列),以及任何你加上的修飾符(比如是否忽略大小寫,或者搜尋全文等等)。

這個規則運算式物件可以用在很多字符串(string)方法中,幫助你處理文本。

以下是一些回傳物件的相關方法:

.test()

如果你只想檢查文本中是否存在符合規則運算式的部分,可以使用 .test() 方法。

這個方法會返回一個布林值(true 或 false),告訴你文本是否匹配你的搜尋條件。

let pattern = new RegExp('apple', 'i');
let text = "Do you like apples?";
let hasApple = pattern.test(text);

console.log(hasApple); 

// 輸出:
// true

.exec()

這個方法接受一個文字參數,並根據規則運算式在該參數文字中搜尋

每次只返回一個匹配結果的陣列資訊(包括匹配的文本、索引等),如果你想要找到所有匹配項,需要多次調用 .exec()。

如果沒有匹配到就返回 null。

let pattern = new RegExp('apple', 'gi');
let text = "Apples are green, and apples are sweet.";
let match;

console.log(pattern.exec(text));
console.log(pattern.exec(text));

// 回傳:

// [
//   'Apple',
//   index: 0,
//   input: 'Apples are green, and apples are sweet.',
//   groups: undefined
// ]

// [
//   'apple',
//   index: 22,
//   input: 'Apples are green, and apples are sweet.',
//   groups: undefined
// ]

new RegExp 與字面量語法的差異

字面量語法

這就像是直接在代碼裡寫下你的搜尋規則,用兩個斜杠包起來,比如:

let regex = /abc/ ;

這種方式簡單直觀,你寫的時候就確定了要搜尋的模式,而且這種方法創建的規則運算式效率更高,因為它在腳本加載時就已經準備好了。

new RegExp

這是一個函數,可以動態地創建規則運算式。

你如果不確定搜尋的模式,想要在運行時根據某些條件來決定,那就用此函數。

let userInput = 'abc';
let regex = new RegExp(userInput);

比如你想根據用戶的輸入來建立一個搜尋模式,就可以先拿到用戶輸入的字符串,然後用 new RegExp(userInput) 這樣的方式來創建。

這種方法靈活,但是相對來說效率不如字面量語法,因為它是在程式運行時才創建的。

主要差異

兩者的主要差異就在於:

  • 確定性:字面量語法在寫代碼的時候就確定了,而 new RegExp 可以在程式運行時根據情況來動態創建。
  • 效率:字面量因為在加載時就已經準備好,所以效率較高;new RegExp 則在需要的時候才創建,效率略低。
  • 靈活性:如果你需要根據不同情況改變搜尋模式,new RegExp 更加靈活。

使用 new RegExp 的場景

new RegExp 的主要優勢在於其動態性。

以下示例展示了如何使用 new RegExp 根據用戶輸入動態生成規則運算式:

// 假設用戶輸入了一個搜索關鍵字
let userInput = "JavaScript";

// 動態創建一個不區分大小寫的搜索規則運算式
let regex = new RegExp(userInput, "i");

// 使用這個規則運算式來搜尋文本
let text = "JavaScript is a programming language.";
let matchResult = text.match(regex);

console.log(matchResult); 

// 輸出:
// ['JavaScript']

延伸閱讀:JavaScript match() 方法:如何輕鬆處理字串匹配

實際應用範例

表單驗證

在網頁應用中,表單驗證是保證用戶輸入數據有效性的關鍵步驟。

利用規則運算式,我們可以實現各種輸入格式的驗證,如電子郵件地址、手機號碼等。

// 驗證電子郵件地址

function validateEmail(email) {
  let emailRegex = new RegExp("^\\S+@\\S+\\.\\S+$");
  return emailRegex.test(email);
}

console.log(validateEmail("example@example.com")); 
// 輸出:
// true

console.log(validateEmail("invalid-email")); 
// 輸出:
// false

在這個範例中,我們使用了 new RegExp 來創建一個簡單的電子郵件驗證規則運算式。

檢查輸入是否包含基本的電子郵件格式:一個 “@” 符號和至少一個點。

字符串搜尋和替換

規則運算式在處理文本數據時特別有用,尤其是在需要搜尋和替換特定模式的字符串時。

// 替換文本中的特定字詞

function censorText(text, forbiddenWordsArray) {
  let pattern = forbiddenWordsArray.join("|");
  let regex = new RegExp(pattern, "gi");
  return text.replace(regex, "****");
}

let result = censorText("This is a secret and confidential document.", ["secret", "confidential"]);
console.log(result); // 輸出:"This is a **** and **** document."

這個範例展示了如何使用 new RegExp 來動態創建一個規則運算式,該規則運算式匹配一組禁用詞並將它們替換為 “****”,達到檢查文本並隱藏敏感資訊的目的。

從文本中提取信息

規則運算式也非常適合於從文本中提取特定格式的信息,例如提取日期、URL、電話號碼等。

// 提取文本中的所有URL

function extractUrls(text) {
  let urlRegex = new RegExp("(https?:\/\/[^\s]+)", "gi");
  return text.match(urlRegex) || [];
}

let text = "Visit our website at https://example.com or our blog at http://blog.example.com.";
let urls = extractUrls(text);

console.log(urls); 

// 輸出:
// ["https://example.com", "http://blog.example.com"]

在這個範例中,我們定義了一個用於匹配 HTTP 和 HTTPS URL 的規則運算式,並通過 match 方法從一段文本中提取所有符合條件的 URL。

結論

在本文中,我們深入探討了 new RegExp 在 JavaScript 中的應用,從基礎概念到進階技巧,再到實際應用範例。

希望幫助你在撰寫代碼時更容易理解、發揮出它的最大價值。

Similar Posts