前端基礎知識JavaScript系列 - 19(正則表達式)

一、是什么

正則表達式是一種用來匹配字符串的強有力的武器

它的設計思想是用一種描述性的語言定義一個規則,凡是符合規則的字符串,我們就認為它“匹配”了,否則,該字符串就是不合法的

在?JavaScript中,正則表達式也是對象,構建正則表達式有兩種方式:

  1. 字面量創建,其由包含在斜杠之間的模式組成
    const re = /\d+/g;
    
  2. 調用RegExp對象的構造函數
const re = new RegExp("\\d+","g");const rul = "\\d+"
const re1 = new RegExp(rul,"g");

使用構建函數創建,第一個參數可以是一個變量,遇到特殊字符\需要使用\\進行轉義

二、匹配規則

常見的校驗規則如下:

規則描述
\轉義
^匹配輸入的開始
$匹配輸入的結束
*匹配前一個表達式 0 次或多次
+匹配前面一個表達式 1 次或者多次。等價于?{1,}
?匹配前面一個表達式 0 次或者 1 次。等價于{0,1}
.默認匹配除換行符之外的任何單個字符
x(?=y)匹配'x'僅僅當'x'后面跟著'y'。這種叫做先行斷言
(?<=y)x匹配'x'僅當'x'前面是'y'.這種叫做后行斷言
x(?!y)僅僅當'x'后面不跟著'y'時匹配'x',這被稱為正向否定查找
(?<!y)x僅僅當'x'前面不是'y'時匹配'x',這被稱為反向否定查找
x|y匹配‘x’或者‘y’
{n}n 是一個正整數,匹配了前面一個字符剛好出現了 n 次
{n,}n是一個正整數,匹配前一個字符至少出現了n次
{n,m}n 和 m 都是整數。匹配前面的字符至少n次,最多m次
[xyz]一個字符集合。匹配方括號中的任意字符
[^xyz]匹配任何沒有包含在方括號中的字符
\b匹配一個詞的邊界,例如在字母和空格之間
\B匹配一個非單詞邊界
\d匹配一個數字
\D匹配一個非數字字符
\f匹配一個換頁符
\n匹配一個換行符
\r匹配一個回車符
\s匹配一個空白字符,包括空格、制表符、換頁符和換行符
\S匹配一個非空白字符
\w匹配一個單字字符(字母、數字或者下劃線)
\W匹配一個非單字字符

正則表達式標記

標志描述
g全局搜索。
i不區分大小寫搜索。
m多行搜索。
s允許?.?匹配換行符。
u使用unicode碼的模式進行匹配。
y執行“粘性(sticky)”搜索,匹配從目標字符串的當前位置開始。

使用方法如下:

var re = /pattern/flags;
var re = new RegExp("pattern", "flags");

在了解下正則表達式基本的之外,還可以掌握幾個正則表達式的特性:

貪婪模式

在了解貪婪模式前,首先舉個例子:

const reg = /ab{1,3}c/

在匹配過程中,嘗試可能的順序是從多往少的方向去嘗試。首先會嘗試bbb,然后再看整個正則是否能匹配。不能匹配時,吐出一個b,即在bb的基礎上,再繼續嘗試,以此重復

如果多個貪婪量詞挨著,則深度優先搜索

const string = "12345";
const regx = /(\d{1,3})(\d{1,3})/;
console.log( string.match(reg) );
// => ["12345", "123", "45", index: 0, input: "12345"]

其中,前面的\d{1,3}匹配的是"123",后面的\d{1,3}匹配的是"45"

懶惰模式

惰性量詞就是在貪婪量詞后面加個問號。表示盡可能少的匹配

其中\d{1,3}?只匹配到一個字符"1",而后面的\d{1,3}匹配了"234"

分組

分組主要是用過()進行實現,比如beyond{3},是匹配d字母3次。而(beyond){3}是匹配beyond三次

()內使用|達到或的效果,如(abc | xxx)可以匹配abc或者xxx

反向引用,巧用$分組捕獲

let str = "John Smith";// 交換名字和姓氏
console.log(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John

三、匹配方法

正則表達式常被用于某些方法,我們可以分成兩類:

  • 字符串(str)方法:matchmatchAllsearchreplacesplit
  • 正則對象下(regexp)的方法:testexec
方法描述
exec一個在字符串中執行查找匹配的RegExp方法,它返回一個數組(未匹配到則返回 null)。
test一個在字符串中測試是否匹配的RegExp方法,它返回 true 或 false。
match一個在字符串中執行查找匹配的String方法,它返回一個數組,在未匹配到時會返回 null。
matchAll一個在字符串中執行查找所有匹配的String方法,它返回一個迭代器(iterator)。
search一個在字符串中測試匹配的String方法,它返回匹配到的位置索引,或者在失敗時返回-1。
replace一個在字符串中執行查找匹配的String方法,并且使用替換字符串替換掉匹配到的子字符串。
split一個使用正則表達式或者一個固定字符串分隔一個字符串,并將分隔后的子字符串存儲到數組中的?String?方法。

str.match(regexp)

str.match(regexp)?方法在字符串?str?中找到匹配?regexp?的字符

如果?regexp?不帶有?g?標記,則它以數組的形式返回第一個匹配項,其中包含分組和屬性?index(匹配項的位置)、input(輸入字符串,等于?str

let str = "I love JavaScript";let result = str.match(/Java(Script)/);console.log( result[0] );     // JavaScript(完全匹配)
console.log( result[1] );     // Script(第一個分組)
console.log( result.length ); // 2// 其他信息:
console.log( result.index );  // 7(匹配位置)
console.log( result.input );  // I love JavaScript(源字符串)

如果?regexp?帶有?g?標記,則它將所有匹配項的數組作為字符串返回,而不包含分組和其他詳細信息

let str = "I love JavaScript";let result = str.match(/Java(Script)/g);console.log( result[0] ); // JavaScript
console.log( result.length ); // 1

如果沒有匹配項,則無論是否帶有標記?g?,都將返回?null

let str = "I love JavaScript";let result = str.match(/HTML/);console.log(result); // null

str.matchAll(regexp)

返回一個包含所有匹配正則表達式的結果及分組捕獲組的迭代器

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';const array = [...str.matchAll(regexp)];console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]

str.search(regexp)

返回第一個匹配項的位置,如果未找到,則返回?-1

let str = "A drop of ink may make a million think";console.log( str.search( /ink/i ) ); // 10(第一個匹配位置)

這里需要注意的是,search?僅查找第一個匹配項

str.replace(regexp)

替換與正則表達式匹配的子串,并返回替換后的字符串。在不設置全局匹配g的時候,只替換第一個匹配成功的字符串片段

const reg1=/javascript/i;
const reg2=/javascript/ig;
console.log('hello Javascript Javascript Javascript'.replace(reg1,'js'));
//hello js Javascript Javascript
console.log('hello Javascript Javascript Javascript'.replace(reg2,'js'));
//hello js js js

str.split(regexp)

使用正則表達式(或子字符串)作為分隔符來分割字符串

console.log('12, 34, 56'.split(/,\s*/)) // 數組 ['12', '34', '56']

regexp.exec(str)

regexp.exec(str)?方法返回字符串?str?中的?regexp?匹配項,與以前的方法不同,它是在正則表達式而不是字符串上調用的

根據正則表達式是否帶有標志?g,它的行為有所不同

如果沒有?g,那么?regexp.exec(str)?返回的第一個匹配與?str.match(regexp)?完全相同

如果有標記?g,調用?regexp.exec(str)?會返回第一個匹配項,并將緊隨其后的位置保存在屬性regexp.lastIndex?中。 下一次同樣的調用會從位置?regexp.lastIndex?開始搜索,返回下一個匹配項,并將其后的位置保存在?regexp.lastIndex?中

let str = 'More about JavaScript at https://javascript.info';
let regexp = /javascript/ig;let result;while (result = regexp.exec(str)) {console.log( `Found ${result[0]} at position ${result.index}` );// Found JavaScript at position 11// Found javascript at position 33
}

regexp.test(str)

查找匹配項,然后返回?true/false?表示是否存在

let str = "I love JavaScript";// 這兩個測試相同
console.log( /love/i.test(str) ); // true

四、應用場景

通過上面的學習,我們對正則表達式有了一定的了解

下面再來看看正則表達式一些案例場景:

驗證QQ合法性(5~15位、全是數字、不以0開頭):

const reg = /^[1-9][0-9]{4,14}$/
const isvalid = patrn.exec(s)

校驗用戶賬號合法性(只能輸入5-20個以字母開頭、可帶數字、“_”、“.”的字串):

var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;
const isvalid = patrn.exec(s)

url參數解析為對象

const protocol = '(?<protocol>https?:)';
const host = '(?<host>(?<hostname>[^/#?:]+)(?::(?<port>\\d+))?)';
const path = '(?<pathname>(?:\\/[^/#?]+)*\\/?)';
const search = '(?<search>(?:\\?[^#]*)?)';
const hash = '(?<hash>(?:#.*)?)';
const reg = new RegExp(`^${protocol}\/\/${host}${path}${search}${hash}$`);
function execURL(url){const result = reg.exec(url);if(result){result.groups.port = result.groups.port || '';return result.groups;}return {protocol:'',host:'',hostname:'',port:'',pathname:'',search:'',hash:'',};
}console.log(execURL('https://localhost:8080/?a=b#xxxx'));
protocol: "https:"
host: "localhost:8080"
hostname: "localhost"
port: "8080"
pathname: "/"
search: "?a=b"
hash: "#xxxx"

再將上面的searchhash進行解析

function execUrlParams(str){str = str.replace(/^[#?&]/,'');const result = {};if(!str){ //如果正則可能配到空字符串,極有可能造成死循環,判斷很重要return result; }const reg = /(?:^|&)([^&=]*)=?([^&]*?)(?=&|$)/ylet exec = reg.exec(str);while(exec){result[exec[1]] = exec[2];exec = reg.exec(str);}return result;
}
console.log(execUrlParams('#'));// {}
console.log(execUrlParams('##'));//{'#':''}
console.log(execUrlParams('?q=3606&src=srp')); //{q: "3606", src: "srp"}
console.log(execUrlParams('test=a=b=c&&==&a='));//{test: "a=b=c", "": "=", a: ""}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86595.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86595.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86595.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java鎖機制知識點

一、鎖的基礎概念 1.1 什么是鎖 在并發編程中&#xff0c;鎖是用于控制多個線程對共享資源進行訪問的機制。鎖可以保證在同一時刻最多只有一個線程訪問共享資源&#xff0c;從而保證數據的一致性。 1.2 鎖的分類 可重入鎖 vs 不可重入鎖&#xff1a;可重入鎖允許同一個線程…

2025下半年軟考軟件設計師(中級)怎么高效備考,目標是穩過線!

25下半年軟考開始進入備考階段&#xff0c;現在咱們就拋開那些文縐縐的官話&#xff0c;用大白話來聊聊2025下半年軟考軟件設計師&#xff08;中級&#xff09;怎么高效備考&#xff0c;目標是穩過線&#xff01; 核心思想&#xff1a;抓大放小&#xff0c;真題為王&#xff0…

Jupyter常見操作(持續更新)

Jupyter常見操作&#xff08;持續更新&#xff09; 本文主要整理一些常見的或者比較簡單的Jupyter操作&#xff0c;盡量保證一次性整理出來&#xff0c;方便需要但是忘記的情況下可以直接查&#xff0c;希望能當字典。 1.查看Jupyter內核 jupyter kernelspec list 2.使用指定…

連點成畫面積計算算法

連點成畫面積計算算法 問題分析與算法設計 1. 問題特征分析 閉合多邊形(起點和終點相同)線段可能交叉形成復雜形狀需要處理自交多邊形可能有多個內部空洞點數較多(≥50個點),需要高效算法2. 解決方案選擇 采用平面掃描算法結合多邊形布爾運算來準確計算最外層邊界包圍的…

華為云Flexus+DeepSeek征文 | 華為云MaaS平臺上的智能客服Agent開發:多渠道融合應用案例

華為云FlexusDeepSeek征文 | 華為云MaaS平臺上的智能客服Agent開發&#xff1a;多渠道融合應用案例 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 總有一行代碼&#xff0c;能點亮萬千星辰。 &#x1f50d; 在技術的宇宙中&#xff0c;我愿做永不…

03.BUG

Bug 1.軟件測試的生命周期2. BUG2.1 表述BUG的要素2.2 BUG級別2.3 BUG的聲命周期 1.軟件測試的生命周期 ? 軟件測試貫穿于軟件的整個生命周期&#xff1a;軟件測試的生命周期&#xff08;Software Testing Life Cycle, STLC&#xff09;,是指測試流程&#xff0c;這個流程是按…

【數據標注師】問答標注

目錄 一、 **問答標注的認知底層架構**1. **三維評估體系**2. **四類問題處理范式** 二、 **五階能力培養體系**? **階段1&#xff1a;問題解析能力筑基&#xff08;2周&#xff09;**? **階段2&#xff1a;答案質量評估訓練**? **階段3&#xff1a;復雜場景處理**? **階段…

使用DBeaver 連接mysql,使用存儲過程插入5萬條數據

使用DBeaver連接MySQL并創建存儲過程生成5萬條數據 連接MySQL數據庫 打開DBeaver&#xff0c;點擊"數據庫"菜單選擇"新建連接"&#xff0c;選擇MySQL驅動。填寫主機、端口、數據庫名稱、用戶名和密碼等信息&#xff0c;測試連接成功后保存。 創建測試表…

某省賽題-windows內存取證

1.獲取admin用戶密碼是多少&#xff1f; 這里我們使用hashdump之后用john爆破沒有結果&#xff0c;然后使用lsadump出來了flag 2.獲取ip和主機名是什么&#xff1f; 主機名&#xff1a; 看注冊表 SAM&#xff1a;記錄了所有的用戶 SYSTEM&#xff1a;可以看主機名 SOFTWARE&a…

【軟考高項論文】論信息系統項目的成本管理

摘要 在信息系統項目管理里&#xff0c;成本管理是極為關鍵的環節&#xff0c;直接影響項目的順利開展與最終成敗。本文結合項目管理實際情況&#xff0c;從項目成本基準的形成過程、項目S曲線的繪制以及成本控制的具體實施三個方面&#xff0c;詳細闡述了對信息系統項目成本管…

AI人工智能技術應用于人社服務領域的創新研究報告

AI 人工智能技術應用于人社服務領域的創新研究報告 一、研究背景與市場概況 1.1 研究背景與政策環境 人工智能技術正深刻改變政府治理模式和公共服務方式。在國家全面推進數字化轉型的戰略背景下,人社部《數字人社建設行動實施方案》明確提出:到 2025 年,人社數字化底座…

javaEE-mybatis操作數據庫

前言 在MySQL的學習階段&#xff0c;我們知道了如何使用JDBC去操作&#xff0c;也正是因為學習了JDBC也知道其操作的繁瑣&#xff0c;每次的CRUD操作都需要從數據庫連接池中去獲取數據庫連接&#xff0c;然后再編寫SQL語句&#xff0c;并綁定對應的參數&#xff0c;接著通過連…

移動端測試——如何解決iOS端無法打開彈窗式網頁(Webkit)

目錄 一、什么是webkit&#xff1f; 1. 核心定義 2. iOS 的特殊限制 3. 彈窗攔截的邏輯 二、為什么 iOS 必須用 WebKit&#xff1f; 1. 蘋果的官方理由 2. 實際后果 3.然而…… 三、如何解決iOS端無法打開彈窗式網頁&#xff1f; 1.用戶 1.1 safari瀏覽器 1.2 夸克…

【github】從本地更新倉庫里的文件筆記

1. 打開GitHub官網&#xff0c;并登錄到您的賬戶。 2. 在頁面右上角的搜索欄中&#xff0c;輸入您要更新的倉庫名稱&#xff0c;并選擇相應的倉庫進入。 3. 在倉庫頁面中&#xff0c;找到并點擊紅色的“Code”按鈕&#xff0c;然后復制倉庫的HTTPS或者SSH鏈接。 4. 右鍵包含…

Excel基礎:數據編輯

Excel是Windows下最常用的數據處理工具&#xff0c;本文詳細介紹Excel的數據編輯功能&#xff0c;熟練掌握編輯技巧能可以極大提升工作效率&#xff0c;文章最后附加了一張總結思維導圖&#xff0c;方便大家查找和記憶。 文章目錄 一、數據輸入1.1 覆蓋輸入1.2 追加輸入1.3 任…

JavaScript中Object()的解析與應用

在JavaScript中&#xff0c;Object() 是一個基礎構造函數&#xff0c;用于創建對象或轉換值為對象類型。它既是語言的核心組成部分&#xff0c;也提供了一系列靜態方法用于對象操作。以下是詳細解析和應用示例&#xff1a; 一、Object() 的基本行為 作為構造函數&#xff08;…

stream使用案例

1.1 查找所有的偶數并求和 public static void p1() { List<Integer> numbers Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int sum numbers.stream() .filter(num -> num % 2 0) .mapToInt(Integer::intValue) .sum() ; System.err.printf…

力扣 刷題(第七十一天)

靈感來源 - 保持更新&#xff0c;努力學習 - python腳本學習 4的冪 解題思路 位運算條件&#xff1a;4 的冪的二進制表示中只有一個 1&#xff0c;且位于奇數位&#xff08;如 4 100&#xff0c;4 10000&#xff09;。模運算條件&#xff1a;4 的冪減 1 后能被 3 整除&…

深度學習使用Pytorch訓練模型步驟

訓練模型是機器學習和深度學習中的核心過程&#xff0c;旨在通過大量數據學習模型參數&#xff0c;以便模型能夠對新的、未見過的數據做出準確的預測。 訓練模型通常包括以下幾個步驟&#xff1a; 1.數據準備&#xff1a; 收集和處理數據&#xff0c;包括清洗、標準化和歸一化…

Unity_導航操作(鼠標控制人物移動)_運動動畫

文章目錄 前言一、Navigation 智能導航地圖烘焙1.創建Plan和NavMesh Surface2.智能導航地圖烘焙 二、MouseManager 鼠標控制人物移動1.給場景添加人物&#xff0c;并給人物添加導航組件2.編寫腳本管理鼠標控制3.給人物編寫腳本&#xff0c;訂閱事件&#xff08;添加方法給Mouse…