JavaScript最後分水嶺——正則表示式!

語言: CN / TW / HK

📜個人簡介

⭐️個人主頁:微風洋洋🙋‍♂️
🍑部落格領域:程式設計基礎,後端
🍅寫作風格:乾貨,乾貨,還是tmd的乾貨
🌸精選專欄【JavaScript】
🚀支援洋鍋:點贊👍、收藏⭐、留言💬

好久不見,甚是想念!
大家好!我是微風洋洋

細心地小夥伴可能已經發現,我的個人簡介中早已出現了洋鍋。為什麼要叫洋鍋呢? 首先呢,大家都知道“一見楊過誤終生”,楊過,洋鍋,諧音豈不美哉! 而且,在我的家鄉洋鍋就是洋哥的意思,不過第二個發音沒找到對應的漢字,就拿鍋來背鍋吧。 好了,切入正題,這篇文章是JavaScript最後一個分水嶺,也是最後一個難關,正則表示式,你一定要挺過去。可能你沒學過,但你肯定也聽過它的大名,很重要。所以洋鍋這次總結的也很詳細,希望能對你有所幫助。

一、認識正則表示式

🍅什麼是正則表示式

⭐️正則表示式(==Regular Expression,簡稱regexp==)

  • 是一種描述字串結構的語法規則。
  • 是一個特定的格式化模式,用於驗證各種字串是否匹配這個特徵,進而實現高階的文字查詢、替換、擷取內容等操作。

應用:在專案開發中,手機號碼指定位數的隱藏、資料採集、敏感詞的過濾以及表單的驗證等功能,都可以利用正則表示式來實現。

適用領域:在作業系統(Unix、Linux等)、程式語言(C、C++、Java、PHP、Python、JavaScript等)。

舉例:以文字查詢為例,若在大量的文字中找出符合某個特徵的字串(如手機號碼),就將這個特徵按照正則表示式的語法寫出來,形成一個計算機程式識別的模式(Pattern),然後計算機程式就會根據這個模式到文字中進行匹配,找出符合規則的字串。

⭐正則表示式的發展史 在這裡插入圖片描述


⭐正則表示式的表現形式

  • 一種是POSIX規範相容的正則表示式,用於確保作業系統之間的可移植性。
  • 一種是當Perl(一種功能豐富的程式語言)發展起來後,衍生出來了Perl正則表示式,JavaScript中的正則語法就是基於Perl的。


🍅如何使用正則

在開發中,經常需要根據正則匹配模式完成對指定字串的搜尋和匹配。

在這裡插入圖片描述


🍑exec()方法

  • ==exec()方法用於在目標字串中搜索匹配,一次僅返回一個匹配結果。==
  • 例如,在指定字串str中搜索abc。

在這裡插入圖片描述

  • “/abc/i”中的“/”是正則表示式的定界符,“abc”表示正則表示式的模式文字,“i”是模式修飾識別符號,表示在str中忽略大小寫。
  • exec()方法的引數是待匹配的字串str,匹配成功時,該方法的返回值是一個數組,否則返回null。
  • 從exec()的返回結果中可以看出,該陣列儲存的第1個元素(AbC)表示匹配到的字串;第2個元素index表示匹配到的字元位於目標字串中的索引值(從0開始計算);第3個引數input表示目標字串(AbC123abc456)。


🍑match()方法

==String物件中的match()方法除了可在字串內檢索指定的值外,還可以在目標字串中根據正則匹配出所有符合要求的內容,匹配成功後將其儲存到陣列中,匹配失敗則返回false。==

在這裡插入圖片描述

  • 定位符“^”,可用於匹配字串開始的位置。
  • 定位符“$”,可用於匹配字串結尾的位置。
  • g表示全域性匹配,用於在找到第一個匹配之後仍然繼續查詢。



🍅獲取正則物件

在JavaScript應用中,使用正則表示式之前首先需要建立正則物件。除了前面講解過的字面量方式建立外,還可以通過RegExp物件的建構函式的方式建立。

在這裡插入圖片描述

  • pattern是由元字元和文字字元組成的正則表示式模式文字。
  • 元字元是具有特殊含義的字元,如“^”、“.”或“*”等。
  • 文字字元就是普通的文字,如字母和數字等。
  • flags表示模式修飾識別符號,用於進一步對正則表示式進行設定。

在這裡插入圖片描述

  • 模式修飾符,還可以根據實際需求多個組合在一起使用。
  • 例如,既要忽視大小寫又要進行全域性匹配,則可以直接使用gi,並且在編寫多個模式修飾符時沒有順序要求。
  • 因此,模式修飾符的合理使用,可使正則表示式變得更加簡潔、直觀。

為了讓讀者更好的理解正則物件的獲取,以匹配特殊字元“^”、“$”、“*”、“.”和“\”為例進行對比講解。

在這裡插入圖片描述

  • 選擇符“|”表示“或”,查詢條件只要其中一個條件滿足即可成立。
  • JavaScript中字串存在轉義問題,因此程式碼中str裡的“\”表示反斜線“\”。
  • 在正則中匹配特殊字元時,也需要反斜線(\)對特殊字元進行轉義。例如,“\\”經過字串轉義後變成“\”,然後正則表示式再用“\”去匹配“\”。

📌注意

建構函式方式與字面量方式建立的正則物件,雖然在功能上完全一致,但它們在語法實現上有一定的區別,前者的pattern在使用時需要對反斜槓(\)進行轉義。而後者的pattern在編寫時,要放在定界符“/”內,flags標記則放在結尾定界符之外



二、字元類別與集合

🍅字元類別

好處:有效的使用字元類別可以使正則表示式更加簡潔,便於閱讀。

舉例1:大寫字母、小寫字母和數字可以使用“\w”直接表示。

案例2:若要匹配0到9之間的數字可以使用“\d”表示。

在這裡插入圖片描述

下面為了方便讀者理解字元類別的使用,以“.”和“\s”為例進行演示.

在這裡插入圖片描述

  • 正則物件reg用於匹配空白符後的任意兩個字元(除換行外)。
  • 因此在控制檯檢視到的結果中,id前有一個空格。



🍅字元集合

字元集合的表示方式:“[]”可以實現一個字元集合。

字元範圍:與連字元“-”一起使用時,表示匹配指定範圍內的字元。

反義字元:元字元“^”與“[]”一起使用時,稱為反義字元。

不在某範圍內: “^”與“[]”一起使用,表示匹配不在指定字元範圍內的字元。

以字串 'get好TB6'.match(/pattern/g) 為例演示其常見的用法。

在這裡插入圖片描述


📌注意

字元“-”在通常情況下只表示一個普通字元,只有在表示字元範圍時才

作為元字元來使用。“-”連字元表示的範圍遵循字元編碼的順序,如“a-Z”、“z-a”、“a-9”都是不合法的範圍。


【案例】限定輸入內容

在這裡插入圖片描述

程式碼實現思路

編寫HTML,設定一個年(份)和月(份)的文字框,以及一個查詢按鈕。

獲取操作的元素物件,對錶單的提交進行驗證。

驗證年份, 正則:/^\d{4}$/。驗證月份,正則: /^((0?[1-9])|(1[012]))$/ 。

文字框獲取焦點,去除提示框的顏色。文字框失去焦點,去除輸入內容的兩端的空白,並進行驗證。


程式碼實現

```javascript

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>限定輸入內容</title>
<style>
input[type=text]{width: 40px;border-color: #bbb;height: 25px;font-size: 14px;border-radius: 2px;outline: 0;border: #ccc 1px solid;padding: 0 10px;-webkit-transition: box-shadow .5s;margin-bottom: 15px;}
input[type=text]:hover, input[type=text]:focus,input[type=submit]:hover{border: 1px solid #56b4ef; box-shadow: inset 0 1px 3px rgba(0,0,0,.05),0 0 8px rgba(82,168,236,.6); -webkit-transition: box-shadow .5s;}
input::-webkit-input-placeholder {color: #999; -webkit-transition: color .5s;}
input:focus::-webkit-input-placeholder, input:hover::-webkit-input-placeholder {color: #c2c2c2; -webkit-transition: color .5s;}
input[type=submit]{height: 30px; width: 80px; background: #4393C9; border:1px solid #fff;color: #fff;font:14px bolder; }
</style>
</head>
<body>
<form id="form">
年份 <input type="text" name="year">
月份 <input type="text" name="month">
<input type="submit" value="查詢">
</form>
<div id="result"></div>
<script>
function checkYear(obj) {
if (!obj.value.match(/^\d{4}$/)) {
obj.style.borderColor = 'red';
result.innerHTML = '輸入錯誤,年份為4位數字表示';
return false;
}
result.innerHTML = '';
return true;
}
function checkMonth(obj) {
if (!obj.value.match(/^((0?[1-9])|(1[012]))$/)) {
obj.style.borderColor = 'red';
result.innerHTML = '輸入錯誤,月份為1~12之間';
return false;
}
result.innerHTML = '';
return true;
}
var form = document.getElementById('form'); // <form>元素物件
var result = document.getElementById('result'); // <div>元素物件
var inputs = document.getElementsByTagName('input'); // <input>元素集合
form.onsubmit = function() {
return checkYear(inputs.year) && checkMonth(inputs.month);
};
inputs.year.onfocus = function() {
this.style.borderColor = '';
};
inputs.month.onfocus = function() {
this.style.borderColor = '';
};
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
// \uFEFF位元組順序標記;\xA0不換行空白
};
}
inputs.year.onblur = function() {
this.value = this.value.trim();
checkYear(this);
};
inputs.month.onblur = function() {
this.value = this.value.trim();
checkMonth(this);
};
</script>
</body>
</html>

```



三、與正則相關的方法

🍅RegExp類中的方法

test()方法:檢測正則表示式與指定的字串是否匹配。

在這裡插入圖片描述

==匹配成功時,test()方法的返回值為true,否則返回false。==

⭐️檢測正則物件的模式修飾符

RegExp類中還有一些屬性,用於檢測當前正則物件使用的模式修飾符,以及指定下一次匹配的起始索引等。

在這裡插入圖片描述


下面為了讀者更好的理解這些屬性的使用,以實現空格的匹配為例進行演示。

在這裡插入圖片描述



🍅String類中的方法

⭐️search()方法:可以返回指定模式的子串在字串首次出現的位置,相對於indexOf()方法來說功能更強大。

在這裡插入圖片描述

  • search()方法的引數是一個正則物件,如果傳入一個非正則表示式物件,則會使用“new RegExp(傳入的引數)”隱式地將其轉換為正則表示式物件。
  • search()方法匹配失敗後的返回值為-1。

⭐️split()方法:用於根據指定的分隔符將一個字串分割成字串陣列,其分割後的字串陣列中不包括分隔符。

當分隔符不只一個時,需要定義正則物件才能夠完成字串的分割操作。

在這裡插入圖片描述

  • 按照字串中的“@”和“.”兩種分隔符進行分割。
  • split()方法的引數為正則表示式模式設定的分隔符,返回值是以陣列形式儲存的分割後的結果。

📌 注意

當字串為空時,split()方法返回的是一個包含一個空字串的陣列“[“”]”,如果字串和分隔符都是空字串,則返回一個空陣列“[]”。

在這裡插入圖片描述

  • 在使用正則匹配方式分割字串時,還可以指定字串分割的次數。
  • 當指定字串分割次數後,若指定的次數小於實際字串中符合規則分割的次數,則最後的返回結果中會忽略其他的分割結果。


動手實踐

密碼強度驗證

密碼強度驗證條件:

① 長度<6位,無密碼強度。

②長度>6位,而且包含數字、字母或其他字元中的一種,密碼強度為“低”。

③長度>6位,而且包含數字、字母或其他字元中的二種,密碼強度為“中”。

④長度>6位,而且包含數字、字母或其他字元中的三種及以上,密碼強度為“高”。



四、字元限定與分組

🍅字元限定


🍑字元限定——限定符

提出問題:匹配一個連續出現的字元,如 6個連續出現的數字“458925”。

解決方案1:正則物件/\d\d\d\d\d\d/gi。

存在的問題:重複出現的“\d”既不便於閱讀,書寫又繁瑣。

解決方案2:使用限定符(?、+、*、{ })完成某個字元連續出現的匹配。正則物件/\d{6}/gi。

在這裡插入圖片描述


🍑字元限定——貪婪與懶惰匹配

當點字元(.)和限定符連用時,可以實現匹配指定數量範圍的任意字元。

  • 舉例:“^hello.*world$”。
  • 說明:可匹配從hello開始到world結束,中間包含零個或多個任意字元的字串。

正則在實現指定數量範圍的任意字元匹配時,支援貪婪匹配和惰性匹配兩種方式。

  • 所謂貪婪表示匹配儘可能多的字元,而惰性表示匹配儘可能少的字元。在預設情況下,是貪婪匹配。
  • 若想要實現惰性匹配,需在上一個限定符的後面加上“?”符號。

在這裡插入圖片描述



🍅括號字元

在正則表示式中,被括號字元“()”括起來的內容,稱之為“子表示式”。

在這裡插入圖片描述

🍑作用

在這裡插入圖片描述

小括號實現了匹配catch和cater,而如果不使用小括號,則變成了catch和er
在這裡插入圖片描述

未分組時,表示匹配2個c字元;而分組後,表示匹配2個“bc”字串。


🍑捕獲與非捕獲

捕獲:將子表示式匹配到的內容儲存到系統的快取區的過程。

非捕獲:不將子表示式的匹配內容存放到系統的快取中,使用(?:x)實現。

在這裡插入圖片描述


String物件的replace()方法,可直接利用$n(n是大於0的正整數)獲取捕獲內容,完成對子表示式捕獲的內容進行替換的操作。

在這裡插入圖片描述

  • 第1個引數為正則表示式,用於與str字串進行匹配,將符合規則的內容利用第2個引數設定的內容進行替換。
  • $2表示reg正則表示式中第2個子表示式被捕獲的內容“Capture”。
  • $1表示第1個子表示式被捕獲的內容“Regular”。
  • 返回值是替換後的新字串,因此,並不會修改原字串的內容。


可以使用”(?:x)”的方式實現非捕獲匹配

在這裡插入圖片描述


🍑反向引用

在編寫正則表示式時,若要在正則表示式中,獲取存放在快取區內的子表示式的捕獲內容,則可以使用“\n”(n是大於0的正整數)的方式引用,這個過程就是“反向引用”。

  • “\1”表示第1個子表示式的捕獲內容。
  • “\2”表示第2個子表示式的捕獲內容,以此類推。

在這裡插入圖片描述

  • “\d”用於匹配0~9之間的任意一個數字。
  • 為其新增圓括號“()”後,即可通過反向引用獲取捕獲的內容。
  • 因此,最後的匹配結果為333和666。


🍑零寬斷言

==零寬斷言==:指的是一種零寬度的子表示式匹配,用於查詢子表示式匹配的內容之前或之後是否含有特定的字符集。

分類:分為正向預查和反向預查,但是在JavaScript中僅支援正向預查,即匹配含有或不含有捕獲內容之前的資料,匹配的結果中不含捕獲的內容。

在這裡插入圖片描述



🍅正則運算子優先順序

正則表示式中的運算子有很多。在實際應用時,各種運算子會遵循優先順序順序進行匹配。正則表示式中常用運算子優先順序,由高到低的順序如下表。

在這裡插入圖片描述

【案例】內容查詢與替換

在這裡插入圖片描述

程式碼實現思路

  • 編寫HTML,定義兩個文字域,一個用於使用者輸入,另一個用於顯示按照要求替換後的過濾內容。
  • 使用者輸入只要含有bad和任意中文字元,就利用*替換。
  • 查詢並替換的內容規則:/(bad)|[\u4e00-\u9fa5]/gi。


程式碼實現

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>內容查詢與替換</title> <style> div{float:left;} input{margin:0 20px;} </style> </head> <body> <div>過濾前內容:<br> <textarea id="pre" rows="10" cols="40"></textarea> <input id="btn" type="button" value="過濾"> </div> <div>過濾後內容:<br> <textarea id="res" rows="10" cols="40"></textarea> </div> <script> document.getElementById('btn').onclick = function () { // 定義查詢並需要替換的內容規則,[\u4e00-\u9fa5]表示匹配任意中文字元 var reg = /(bad)|[\u4e00-\u9fa5]/gi; var str = document.getElementById('pre').value; var newstr = str.replace(reg, '*'); document.getElementById('res').innerHTML = newstr; }; </script> </body> </html>


如果覺得這篇文章對你有一丟丟啟發的話,不妨 點贊👍、收藏⭐、留言💬支援一下,你的支援將是我繼續創作的最大動力❤️❤️❤️

由於作者水平有限,如有錯誤和不準確之處在所難免,本人也很想知道這些錯誤,懇望讀者批評指正!

if (學會了){
點贊收藏給個好評,我祝福您學啥會啥;
}else{
點贊收藏給個好評,我相信您定能學會;
}