JavaScript >> Javascript 文檔 >  >> Tags >> string

JavaScript 中的正則表達式和匹配字符串指南

簡介

匹配字符串或字符串模式可能是一場真正的鬥爭。在最常見的情況下,您將需要這些來驗證電子郵件、用戶輸入、文件名 ,或大多數類型的輸入字符串。雖然有許多模式匹配庫和方法 - 一種經過時間考驗的方法是使用 正則表達式 定義一組規則,某個字符串必須遵循才能匹配該模式。

在 JavaScript 中,RegExp 用於表示正則表達式的類 並且可以與一些使匹配模式更容易的方法相結合。

顯然,使用這些的先決條件是了解正則表達式 .如果您對編寫它們感到不自在,您可以隨時使用 RegEx 測試網站,例如 regex101.com 或 regexr.com,它們可以直觀地顯示您的表達式對給定字符串的影響。

之後,我們將看看使用 String 實現的一些方法 對象 - match() , search()replace() ,它使用正則表達式作為使用 RegExp 的更短的替代方法 類。

什麼是正則表達式?

在我們深入研究用於使用 RegEx 的 JavaScript API 之前,讓我們先來看看正則表達式本身。如果您已經熟悉它們 - 這可以作為複習,或者您可以完全跳過該部分。

一個正則表達式 (縮寫。RegEx ) 是一種字符模式,用於匹配字符串或字符的不同組合。為了形成正確的正則表達式,您需要遵循某些規則。我們將快速瀏覽這些內容並舉例說明:

  • [abc] - 匹配單個字符 :a、b 或 c
  • [^abc] - 匹配每個字符除了 a、b 或 c
  • [a-z] - 匹配 範圍 a-z 中的任何字符
  • \s - 匹配任何 空格 人物
  • \w - 匹配任何單詞 人物

這些是一些基本 模式,但它們可以讓你走得更遠。正則表達式也支持運算符:

  • a? - 運算符 ? 匹配 0 或 1 字符 a
  • a* - 運算符 * 匹配零個或多個 字符 a
  • a+ - 運算符 + 匹配一個或多個 字符 a
  • a{n} - 運算符 {n} 匹配字符 a 完全正確 n 連續幾次
  • a{n, m} - 運算符 {n, m} 匹配字符 a n 之間 和 m 連續幾次
  • \. - 運算符 \ 轉義字符 . , 表示字符 . 不會有它通常的含義 - 匹配任何字符串 - 但將作為字符匹配 .

為了將其付諸實踐 - 讓我們編寫一個正則表達式來檢查字符串是否包含 @gmail.com 在字符串的末尾並包含三個字符 a @ 之前 符號:

"\w+a{3}@gmail\.com"

讓我們快速分解一下:

  • \w - 匹配任何字符
  • a{3} - 匹配三個字符 a 連續
  • @gmail\.com - 匹配文字字符串 "@gmail.com" , 同時轉義 . 帶有 \ 運營商

有了這個 RegEx ,我們可以匹配這樣的字符串:

[email protected]
[email protected]

但不是:

[email protected]
[email protected]
[email protected]

你也可以在可視化的 RegEx 測試器中測試這些,看看哪些部分匹配以及為什麼匹配。

正則表達式

在 JavaScript 中,有兩種​​創建正則表達式的方法:

  1. 使用 RegEx 文字 ,這是放在 / 之間的模式 字符:
let regex = "/[abc]+/";

如果您的 RegEx 在整個腳本中保持不變,您應該使用這種方法,因為此 RegEx 是在腳本自動加載時編譯的。

  1. 使用 RegExp() 構造函數:
let regex = new RegExp("[abc]+");

當您的 RegEx 是動態的並且可以在腳本的整個生命週期中更改時,這種方法是首選。它在運行時編譯 ,而不是加載時間 .

注意: 從 ES6 開始,您還可以傳遞 RegEx 文字 作為構造函數的參數:

let regex = new RegExp(/[abc]+/);

使用 RegExp 時 ,您還可以傳遞標誌 - 具有含義的字符 - 這會改變模式匹配的方式。其中一些標誌是:

  • i - 表示不區分大小寫 ,所以 Aa 匹配時是一樣的
// Matches both ABC and abc one or more times
let regex = new RegExp("[abc]+", "i"); 
  • g - 表示將匹配所有可能的情況,而不僅僅是遇到的第一個情況

  • m - 表示多行模式 ,它允許模式與多行編寫的字符串匹配

let string = `
This string can also be matched with
Even though it's written in multiple lines
`

RegExp() 構造函數僅用於創建要測試的模式。但是,它包含兩種方法可以測試模式並匹配它:exec()test() .

exec() 方法

exec() 方法,毫不奇怪,執行 在字符串中搜索。如果有匹配,則返回一個包含匹配信息的數組,否則返回null .

讓我們在電子郵件示例中進行測試 - 我們正在檢查電子郵件是否以 @gmail.com 結尾 並包含三個連續的a @gmail 之前的字符 域。

此外,我們將使用 不區分大小寫的標誌

let regex = new RegExp(/\w+a{3}@gmail\.com/, "i");

let result1 = regex.exec("[email protected]");
let result2 = regex.exec("[email protected]");

console.log(result1);
console.log(result2);

或者您可以為 null 應用 Null Coalescing Operator -安全:

let regex = new RegExp(/\w+a{3}@gmail\.com/, "i");

let result1 = regex.exec("[email protected]") ?? 'No matched results';
let result2 = regex.exec("[email protected]") ?? 'No matched results';

我們來看看輸出:

[ '[email protected]',
  index: 0,
  input: '[email protected]',
  groups: undefined ]
  
[ '[email protected]',
  index: 0,
  input: '[email protected]',
  groups: undefined ]

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

這個數組包含多個東西:

  1. 匹配的字符串
  2. 索引值 匹配字符串的起始位置
  3. 輸入字符串
  4. groups 屬性 它包含所有命名捕獲組的對象 - 在大多數情況下,這將是 undefined

如果你希望只隔離匹配的字符串而不需要額外的信息,你可以打印出來

console.log(results[0])

exec() 的一個有趣功能 方法是它記住它停止執行的字符的索引 ,所以基本上,你可以一次又一次地調用這個方法,直到你得到一個 null 作為回報。

此屬性稱為 lastIndex .為了實現這一點,您可以傳遞一個 字符串數組exec() 而不是單個字符串。

讓我們傳遞一個包含三個字符串的數組;其中兩個將匹配,一個不會。為了得到多個結果,我們可以循環遍歷數組並調用exec() 直到我們得到一個 null .另外,讓我們創建一個空數組 matchedStrings 並將匹配的字符串推送給它。

注意 :你必須 通過 g 標記到 RegExp() 構造函數以獲取所有結果,而不僅僅是第一個。這樣,你就可以避免陷入無限循環,而且沒有人喜歡無限循環。

let regex = new RegExp(/\w+a{3}@gmail\.com/, "g");

let strings = ["[email protected]", "[email protected]", "[email protected]"];
let matchedStrings = [];

let result = regex.exec(strings);
if(result != null) {
    matchedStrings.push(result[0]);
}

while(result != null) {
    result = regex.exec(strings);
    if(result != null) {
        matchedStrings.push(result[0]);
    }
}

console.log(matchedStrings);

這導致:

 ["[email protected]", "[email protected]"]

你可以看到我們從來沒有跟踪數組中最後執行的字符串的索引,但是 exec() 知道在哪裡繼續搜索。很整潔!

test() 方法

test() 方法類似於 exec() 除了它不返回包含信息的數組,而是一個簡單的 truefalse .它執行與 exec() 相同的搜索 如果模式與字符串匹配,則返回 true .否則,它返回 false

let regex = new RegExp(/\w+a{3}@gmail\.com/, "i");

let results = regex.test("[email protected]");
console.log(results); // Output: true

results = regex.test("[email protected]");
console.log(results); // Output: false

此方法無法返回 null ,並且您可以使用結果來指示進一步的條件邏輯。

test() 方法還記得 lastIndex 的執行,所以你可以測試出一個字符串數組。但是,如果你測試同一個字符串兩次,你會得到不同的結果:

let regex = new RegExp(/\w+a{3}@gmail\.com/, "g"); // Remember the 'g' flag when working with multiple results

let results = regex.test("[email protected]");
console.log(results); // Output: true

results = regex.test("[email protected]");
console.log(results); // Output: false

我們得到 false 的原因 第二次是因為 lastIndex 已移動到字符串的末尾,因此當它第二次開始搜索時 - 它從字符串的末尾開始 - 沒有可匹配的內容。因此,它返回 false .

如果您使用 test(),則必須確保不重複 預期行為 .

test() 的用法 字符串數組與 exec() 相同 ,除了您將打印出 true /false .實際上,這並不常用,除非您跟踪匹配字符串的數量。

match() 方法

match() 方法是 String 的第一個 我們將要研究的方法 - 它適用於 正則表達式 .
這需要一個RegEx 作為參數並返回一個匹配數組null 如果沒有,那麼本質上 - 與 exec() 的 API 大致相同 RegEx 的方法 實例:

let regex = new RegExp(/\w+a{3}@gmail\.com/, "g"); // Note the 'g' flag

let string = "[email protected]";
let resultArray = string.match(regex);

console.log(resultArray); // Output: [ '[email protected]' ]

注意: 您也可以使用 RegEx 文字 此處改為縮短代碼,因為它已編譯為 RegEx 無論如何實例:

let string = "[email protected]";
let resultArray = string.match(/\w+a{3}@gmail\.com/);

console.log(resultArray); // Output: [ '[email protected]' ]

為了更好地了解該方法,讓我們將 RegEx 更改為 /[a-z]/ - 只匹配小寫字符:

let regex = new RegExp(/[a-z]/, "g"); // Note the 'g' flag

let string = "[email protected]";
let resultArray = string.match(regex);

console.log(resultArray);

這導致字符串中所有小寫字符的數組:

["s","o","m","e","m","a","i","l","a","a","a","g","m","a","i","l","c","o","m"]

search() 方法

search() 方法搜索 用於傳遞的模式和字符串之間的匹配。如果找到匹配項,則其 index 被退回。否則,該方法返回 -1

let regex = new RegExp(/\w+a{3}@gmail\.com/, "g"); // Note the 'g' flag

let string = "some string that isn't matched [email protected]";
let result = string.search(regex);

console.log(result); // Output: 31

string = "It should return -1 with this string";
result = string.search(regex);

console.log(result); // Output: -1

當您想找出是否找到匹配項時,應使用此方法 它的索引。如果您只想知道是否找到匹配項,則應使用 test() .

您還可以從 exec() 中提取此信息 方法,但這需要您匹配數組中的元素,這會返回更容易解析的結果。

replace() 方法

replace(to_replace, replace_with) 方法返回一個新字符串,其中模式匹配 to_replace 替換為 replace_with .

to_replace 參數可以是字符串或 RegExp 實例。如果它是一個字符串,只有第一個匹配項將被替換,而如果它是一個 RegExp ,每一個都會被替換。

為了這個方法的目的,讓我們替換 gmail.comyahoo.com .

let regex = new RegExp(/gmail\.com/, "g"); // Note the 'g' flag

let string = "[email protected]";
let result = string.replace(regex, "yahoo.com");

console.log(result); // Output: [email protected]

string = "[email protected] [email protected]"
result = string.replace(regex, "yahoo.com");

console.log(result); // Output: [email protected] [email protected]

console.log(string); // Output: [email protected] [email protected]

正如您在第二個示例中看到的,所有匹配 regex 替換為 yahoo.com .此外,原始字符串保持不變。

結論

儘管正則表達式可能難以閱讀,並且起初可能難以理解,但在理解它們之後,使用它們並構建它們會非常有趣。

JavaScript 確保讓測試和匹配盡可能簡單,您需要做的就是學習正則表達式。

但是,借助當今可用的工具以及與指南開頭列出的網站類似的網站,您可以很容易地實際學習正則表達式的所有規則。

在本指南中,我們介紹了:

  • RegExp - 一個類,其對像用於表示正則表達式
  • exec() 方法 - 在字符串中搜索正則表達式 並返回一個匹配數組(帶有附加信息)。
  • test() 方法 - 僅測試字符串中是否匹配並返回 true /false .
  • match() 方法 - String 中定義 類 , 返回匹配的數組(不包含其他信息)。
  • search() 方法 - String 中定義 類 , 返回找到的匹配的索引。
  • replace() 方法 - String 中定義 類 , 替換 RegExp() 用一個字符串。

正則表達式的最佳實踐可能是嘗試並測試用於電子郵件和密碼驗證的那些。


Tutorial JavaScript 教程
  1. 將 Material-UI 從 v4 升級到 v5,性能提升 55%

  2. 在 5 分鐘內可視化您的 Node.js 應用程序的架構

  3. 如何使用終端打開 VSCode

  4. beCoditive API

  5. 將所選文本複製到剪貼板而不使用 Flash - 必須是跨瀏覽器

  6. 如何在 Vue js 中使用 arcgis js

  7. 在 10 分鐘內構建一個繪畫應用程序!

  1. 帶有 React 的冠狀病毒信息儀表板

  2. 使用 JavaScript、SVG 和 CSS-JSitor 的交互式菜單欄

  3. 如何在回調中訪問正確的 this

  4. 不到 3 小時學習 Vue JS 並搭建網站

  5. 開發模式下 Dockerfile 和 Docker-compose 的目的是什麼?

  6. 反應代碼拆分

  7. 梳理,但有閃光

  1. 使用 Cypress 進行 API 測試:第 2 部分 - 創建測試

  2. 使用 Google Chrome 逐行調試 Javascript

  3. 2020 年最佳類似 React 的 JSX UI 庫

  4. 免費的 React 儀表板 - Chakra、M-UI 和 Ant Design