JavaScript的正則表達式總結學習

最近複習JavaScript基礎知識夯實基礎,發現有很多短板。其中之一便爲正則表達式,在進行了相對系統的總結學習之後,在這裏做一番自己的總結。以備之後便捷查詢更改。

一:正則的基本概念以及作用

概念:
正則表達式也被稱爲規則表達式,通常被用於檢索,替換某些規則的文本。
不必對概念糾結,簡單的將正則表達式理解爲一個匹配規則即可。
作用:
正則表達式在不同的編程語言中有着不同的表現形式,在這裏使用JavaScript前端語言進行舉例並且說明
經常會遇見一個替換場景,例如將字符串'a1b1c1d1'中的數字全部替換成大寫字母X

'a1b1c1d1'.replace('1', 'X')        // 結果爲: 'aXbXcXdX' 

但是當需要替換字符串'a1b2c3d4'中的所有的數字爲大寫字母X時需要怎麼做?
是不是有些繁瑣,在這裏使用正則表達式將會非常的方便

'a1b2c3d4'.replace(/\d/g, 'X')    // 結果爲:    'aXbXcXdX' 

即使不使用正則表達式他也會將匹配字符轉換成正則規則,再進行匹配,因此使用正則將會更加方便

二:正則表達式的使用基礎知識

1:創建正則的兩個方式
在javascript中,通常通過使用內置對象:RegExp對象來支持使用正則表達式
1):通過創建變量的方式(常用)

var reg = /\d/g;

2):通過創建對象的方式

var reg = new RegExp('\\d', g)     
// 第一個參數爲正則表達式,在字符串中\屬於特殊字符, 因此必須要進行轉義;
// 第二個參數是修飾符,

2:正則表達式的修飾符

  1. global 簡寫:g 全局匹配
  2. ignore case 簡寫:i 忽略大小寫
  3. multiple lines 簡寫: m 多行搜索
    正則表達式的修飾符可以多個一起使用修飾正則表達式。

3:正則表達式的兩種字符類型

  1. 原義文本字符
    即表達式中的字符和要匹配的字符是一樣的,沒有特殊含義。
  2. 元字符
    在正則表達式中有特殊含義的非字母字符
    例如: * + ? $ ^ . | \ ( ) { } [ ]
    注意:元字符的含義並不是唯一的,在不同的場景下,他也是不同的。

4:正則表達式的類
在描述表達式中的類之前,大家都明白,凡是類,必定就是一個泛指,他代表的是一類字符。
1:字符類
使用【】來構建類
【abc】表示將a或b或c歸爲一類,表示one of,有其中一個即可。
注意常用字符類取反^
【^abc】 表示 none of 不屬於這三者中的任意一個。
2:範圍類
如果只是用字符類去匹配某幾個字符,可以以字符類的形式直接寫出來,但是當匹配的是所有的數字,或者是26個字母時,如果全部都列舉出來例如[0123456789]是不是麻煩了一點? 此時就需要範圍類。

[0-9]  // 表示所有的數字
[a-z]  // 表示所有的小寫字母
[A-Z]  // 表示所有的大寫字母
[a-zA-Z] // 表示所有的大小寫字母

5:JavaScript中正則表達式的預定義類和邊界
1:預定義類
在正則表達式中有很多的預定義的類,用於替換寫法較爲繁瑣的正則。

預定義類 等價類與意義
. [^\r\n]除回車符和換行符外的所有字符
\d [0~9] 數字字符
\D [^0~9]非數字字符
\s [\t\n\x0B\f\r]空白字符
\S [^\t\n\x0B\f\r]非空白字符
\w [a-zA-Z_0-9]單詞字符(字母數字下劃線)
\W [^a-zA-Z_0-9]非單詞字符

2:邊界
例如有字符串 This is a boy需要匹配單詞is,

var reg = /\bis\b/g

此時就需要使用單詞邊界 \b

邊界 含義
^ 以XX開始(在正則的前面進行添加)
$ 以XX結束(在正則的後面添加)
\b 單詞邊界
\B 非單詞邊界

6:正則表達式的量詞
當一個字符出現多次時,將匹配規則重寫多次是不現實的,況且也不知道他具體出現的次數,因此量詞的出現就更加具有意義。

量詞符號 等價寫法與意義
{0,1}表示最多隻出現一次
+ {1,}表示至少出現一次
* {0,}表示出現任意次
{n} 出現n次
{n,m} 出現n到m次
{n,} 至少出現n次

注意量詞只會作用於緊挨着他的那個字符,並不是整體,因此需要配合分組進行使用

(boy){3}

7:js正則的貪婪模式和非貪婪模式
所謂的貪婪模式就是負責到底,他會根據匹配的規則將要驗證的字符串整體的進行驗證,所有符合條件規則的字符都會被檢測出來。非貪婪模式則反之,有一種得過且過的慵懶,只要有一個符合即可。
通常在正則中的量詞後面使用切換到非貪婪模式
8:分組
在前面量詞的描述中已經接觸過分組,其實在後面的或(|)中也需要使用分組來明確正則的匹配範圍,因此分組在正則中的作用非常的大。
1):常規寫法
var reg = /([a-z]\d){3}/g
定義小寫字母后面緊挨着數字的組合字符串出現三次的規則。
如果沒有()量詞緊挨着\d則表示一個小寫字母后面緊挨着三個數字。
2):或的表示

var reg =  /(Lo|Li)/g

定義全局查詢存在Lo或者Li的字符串的規則。
3):反向引用
在分組中通常使用$來代表每一個分組

  var str = '2015-11-20'
  var reg = /(\d{4})-(\d{2})-(\d{2})/g
  str.replace(reg, '$2/$3/$1')

把’2015-11-20’替換成 '11/20/2015’的形式,需要使用分組將其中的數據提取出來,再進行重新的拼接即可。

9:正則表達式的前瞻
在正則表達式中正則表達式的匹配規則是從文本的頭部向尾部進行匹配的,因此文本尾部的方向稱爲前。
而前瞻只是比普通的正則匹配多了一個斷言,他在使用正則匹配到符合條件的數據之後,他還要檢查一下是否符合斷言中的要求。相對於單一的正則匹配,他還多了一個斷言檢測。同時需要注意的是斷言只是起到檢測判斷作用,並不會進行匹配

var str = 'a1*34dv4'
var reg = /\w(?=\d)/g   // 正向前瞻 匹配一個單詞字符,要求他前面必須是一個數字
str.replace(reg, 'X')     //結果爲:X1*X4dX4
類型 符號
正向前瞻 exp(?=assert)
反向前瞻 exp(?!assert)

10:正則表達式的屬性
正則表達式的屬性都是隻讀的並不能手動進行賦值。

屬性 意義
global 是否全局搜索匹配
ignoreCase 是否忽略大小寫
multiline 是否多行匹配搜索
lastIndex 當前表達式匹配內容的最後一個字符的下一個位置
source 正則表達式文本本內容

注意:lastIndex屬性只在全局匹配時纔有效,不是全局匹配是無效的,因爲實現全局匹配的前提是他可以在上一個匹配字符的後一個字符位置開始進行檢索,因此lastIndex只有在全局匹配時纔有意義,當非全局匹配時,他爲0表示無效。

三:方法使用

前面描述的都是關於正則的一些基礎知識,下面的一些方法,纔是使用頻率較高的一些功法,現在一一羅列進行總結。
1:正則表達式本身的兩個方法
1):test方法

RegExp.prototype.test(str)

test方法用於測試字符串中是否有匹配正則規則的字符串,存在返回true,不存在返回false。當正則爲全局匹配時,它具有一些隱患,也是由於全局匹配中的lastIndex造成的

  var reg1 = /\w/
  var reg2 = /\w/g
  reg1.test('ab')   // 不論執行多次,都會爲true
  reg2.test('ab')  
  // 前兩次是true,第三次是false。lastIndex指向了最後一個字符所在的位置。
  // 這種現象是由於lastIndex導致的,去掉全局匹配即可。
  // 非全局狀態下,是沒有lastIndex屬性的

2):exec方法

RegExp.prototype.exce(str)

檢測字符串中有沒有符合匹配規則的字符串。如果沒有返回null,如果有則返回一個結果數組。同時數組還有兩個屬性: (1)index屬性:聲明匹配文本的的第一個字符的位置;(2)input屬性:存放被檢索到的string
非全局調用(適用於只獲取第一個匹配結果)

 var reg = /\d(\w)\d/
 var str = '1z2xx3c4v5'
 reg.exec(str)
 // 匹配結果爲:(多次調用結果還是一樣)  ['1z2', z]

全局調用(適用於獲取所有的匹配結果)

 var reg = /\d(\w)\d/g
 var str = '1z2xx3c4v5'
 reg.exec(str)
 //第一次執行:['1z2', z]
 //第二次執行:['3c4', c]
 //第三次執行: null

2:字符串的方法

方法  1:String.prototype.search(reg)

search方法用於檢索字符串中的指定子字符串,或者是檢索與正則匹配的字符串,匹配到返回index,匹配不到返回-1; 注意serach方法自動忽略全局匹配g 即他每次查找都是從字符串的起點開始

方法  2: String.prototype.match(reg)

match方法用於檢索字符串,以找到一個或者多個與RegExp匹配的文本。
它也分爲全局匹配和非全局匹配兩種,和exec方法相類似
match的非全局匹配:
1: 只執行依次匹配,如果成功,就返回一個相關數組,如果不成功就返回null
2: 類比正則表達式的方法exec方法
1):返回值是一個數組;
2):數組的第一個元素是第一個匹配的文本,其他項則是當有分組時,存放分組的匹配字符
3): 數組還有兩個屬性,: index 和 input 和exec是一樣的
match的全局匹配:
1:匹配成功返回數組,否則返回null
2:如果返回的是一個數組,不同於非全局的匹配,他沒有那麼多的額外信息,數組中的每一項都是匹配上的字符,而沒有分組的字符
3: 沒有index屬性 (undefined) 沒有input屬性 沒有lastIndex (爲0)

方法 3: String.prototype.split(reg)

例如:split 方法將字符串分割成數組

'a1b2c3d4e'.split(/\d/g)   // 結果爲:[a,b,c,d,e]   
方法 4:  String.prototype.replace()

三種替換形式
1: replace(str, replaceStr)
2: replace(reg, replaceStr)
3: replace(reg, function) 用function的返回值作爲他的替換結果
function的參數
function會在每一次匹配時被調用到,有四個參數
1):第一個參數是匹配的字符串 match
2):第二個參數乃至後面更多的參數是分組 group : group1 group2… 如果有分組就寫,沒有分組就不寫
3):第三個參數爲匹配項在字符串中index
4):第四個參數爲原字符串 origin

 'a1b2c3d4e5f6'.replace(/(\d)(\w)(\d)/g, function(match, group1, group2,
 								 group3, origin){
             console.log(match)           // 輸出結果爲:  '1b2' , '3d4', '5f6'                         
             return  group1 + group3   // 最後的替換結果爲  : 'a12c34e56'
                           })

四:最後的話

學習完教程之後總結出上述所有的內容;篇幅較長,一字一字敲出來,裏面內容或有差錯,希望有錯誤或者疑問能夠不吝嗇的提出來,共同進行探討。
最後
青春是用來奮鬥的,青春也是用來回憶的
希望回憶過往時雖有坎坷與挫折,但也包含成功的自豪喜悅。
願每一份深情都被真誠相待。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章