JS之Regex

來源:互聯網
上載者:User

標籤:方式   表達   []   相關   多行   取反   Regex文法   種類   ase   

  Regex(英文:regular expression),是一種符合某種文法規則的文本。同時可以理解為使用單個字串來描述,匹配一系列的符合某種文法規則的字串。許多語言都有著符合自己文法規範的Regex,如java,python,php,js。雖然這些正則不是完全一樣,但也是大同小異。今天我想重點說的是JS中的Regex。

 

  Regex的功能十分強大,能夠熟練掌握它能夠為平時的學習和工作帶來不少的便利。雖然正則理解入門不是很難,但是真正地去掌握它並且熟練地運用起來卻不是一件容易的事情。

 

  學習正則有一個很好的線上的網站 https://regexper.com/  。它可以協助你更好的理解Regex中的一些關係。

 

Regex基礎文法內容

1.1Regex的構造

  在js中,Regex有兩種構造方式。一種是常用的字面量標記法,即將正則字串寫在/(regexp)/

  例如要匹配一個數字

var reg=/\d/;

  還有一種是建構函式的方法,即new RegExp()。該方法有接收兩個參數,第一個參數是正則字串,第二個是匹配的模式(下文會講)。但是第一個參數比較特殊,在逸出字元時同時要轉義逸出字元,即若是用這種方法匹配一個數字,

var reg=new RegExp(‘\\d‘,‘g‘);

1.2Regex的匹配模式

  常見匹配模式有三種,即全域匹配g,不區分大小寫i,多行搜尋匹配m。

‘abcd‘.replace(/[a-z]/,‘1‘)  //‘1dcd‘  只匹配一次‘abcd‘.replace(/[a-z]/g,‘1‘) //‘1111‘  都可以被匹配‘ABcd‘.replace(/[a-z]/,‘1‘)  // ‘AB1d‘ ‘ABcd‘.replace(/[a-z]/gi,‘1‘) //‘1111‘‘abc‘.replace(/^[a-z]/,‘1‘) //‘1bc‘//分行符號隔開‘abc‘.replace(/^[a-z]/m,‘1‘) //‘111‘

 

2.Regex文法

2.1元字元

  Regex由兩種基底字元類型組成:①.原義文本字元,就是字元本身代表的意思。如 a 匹配 a ,1匹配1     ②.元字元,即正則中有特殊含義的非字母字元 如  *  +  ?  $  ^ . |  \ ()  {}  []

  元字元構成了許多有意義的特殊字元,例如 \t 水平定位字元  \v垂直定位字元  \n分行符號  \r斷行符號符  \0Null 字元  \f換頁符  

2.2字元類

  一般情況下正則中一個字元匹配字串中的一個字元,但是可以用元字元[]來構建一個符合某種特性的類,即符合這種特性的字元都可以被匹配。如[a,b,c]匹配a或b或c

‘abcd‘.replace(/[abc]/g,‘d‘)   //‘dddd‘   即abc都可以被匹配

2.2.1字元類取反

  使用元字元^可以建立反向類,即不屬於某種類的內容 如[^abc]匹配不是abc的字元

‘abcde‘.replace(/[^abc]/g,‘x‘)  //‘abcxx‘  即把不是abc的字元替換為x

2.2.2範圍類

  可以在[]中用-來串連兩個字元表示範圍  如[a-z]相當於[abcd.....xyz],[0-9]相當於[0123456789],這樣帶來了許多便利。

  在範圍類的內部可以連寫。如[a-zA-Z]匹配所有大小寫字母。如果要匹配-則要在之後加上-,在兩個字元之間的-表示範圍。

‘1970-01-01‘.replace(/[0-9]/g,‘a‘)  //‘aaaa-aa-aa‘ ‘1970-01-01‘.replace(/[0-9-]/g,‘a‘)   //‘aaaaaaaaaa‘

2.2.3預定義類

  ①.可以匹配常見的字元類.

  例如  .匹配除了斷行符號符和分行符號(\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])匹配非單詞字元.

  ②.邊界匹配字元.如^  表示以xxx開頭(這裡要注意區分開反向類,它在[]外,在[]內部表示取反)  $表示以xxx結尾  \b表示單詞邊界  \B表示非單詞邊界。

2.3量詞

  量詞表示可以匹配任意數量的字串.如?表示匹配0次或1次,+表示匹配1次或多次,*表示匹配0次或多次 ,{n}表示匹配n次,{n,m}表示匹配n次到m次,{n,}表示匹配至少n次

‘abcd‘.replace(/[a-z]?/,‘x‘)  //‘xbcd‘‘abcd‘.replace(/[a-z]+/,‘x‘) //‘x‘‘abcd‘.replace(/[a-z]*/,‘x‘)  //‘x‘‘abcd‘.replace(/[a-z]{2,3}/,‘x‘) // ‘xd‘以上都是在貪婪模式下匹配返回的字串,這是正則預設的匹配模式,下文會詳細說明

2.4貪婪模式與非貪婪模式.

  貪婪模式是正則表示式預設的匹配模式,即儘可能多的匹配字元。非貪婪模式則相反,儘可能少的匹配,一旦匹配成功則不再嘗試。

  貪婪模式如下

‘12345678‘.replace(/\d{3,6}/g,‘0‘)  //‘078‘

  非貪婪模式,只需在量詞後加上?就可以了。

‘12345678‘.replace(/\d{3,6}?/g,‘0‘)  //‘0078‘

2.5分組

  ①分組表示可以將不同的正則分為一組去匹配字串。用()括起來的部分表示一個分組。如([a-z]\d)表示一個小寫字母與一個數字為一組

‘a1b2c3d4‘.replace(/([a-z]\d){3}/g,‘x‘) //‘xd4‘

  ②或,用 | 表示。例如

‘cathatbat‘.replace(/[c|h|b]at/g,‘x‘) // ‘xxx‘

  ③反向引用,在正則中很重要的一個方法.$1,$2,$3...$n表示的是分組內的內容,分組上文講過用()括起來的是一個分組,用$捕獲分組內的內容,也叫擷取的群組。

  如要將1970-01-01替換成01/01/1970

‘1970-01-01‘.replace(/(\d{4})-(\d{2})-(\d{2})/g,‘$2/$3/$1‘)// 01/01/1970

  ④忽略分組,若不希望捕獲某些分組,只需要在分組內加上?: 就可以了

 2.6前瞻後顧

  前瞻就是Regex匹配到規則時,向前檢查是否符合斷言,後顧方向相反。JS中不支援後顧。

  正向前瞻 exp(?=assert)

 

‘a2*3‘.replace(/\w(?=\d)/g,‘x‘)  //‘x2*3‘

 

   負向前瞻 exp(?!assert)

 

‘a2*3‘.replace(/\w(?!\d)/g,‘x‘)  //  ‘ax*3‘

 

3.RegExp對象

3.1.RegExp對象屬性

global:是否全文檢索搜尋,預設為false,唯讀

ingore case:是否大小寫敏感,預設為false,唯讀

multiline:是否多行搜尋,預設為false,唯讀

lastIndex:當前運算式匹配內容的最後一個字元的下一個字元的位置,只在全域匹配中有作用

source:Regex的文本字串

3.2.RegExp對象的相關方法

①.RegExp.prototype.test(str)

用於測試字串參數中是否存在匹配Regex模式的字串,存在返回true,不存在返回false

這裡要注意一個問題,就是關於lastIndex指向問題

var reg=/\w/g ;reg.test(‘ab‘) //第一次  返回true 沒問題reg.test(‘ab‘) //第二次  返回true  沒問題reg.test(‘ab‘) //第三次  返回false  有問題

reg.test(‘ab‘) //第四次 返回true
while(reg.test(‘ab‘)){ console.log(reg.lastIndex); }// 1 2

Regex對象每次匹配都作用在正則表示式本身,每次匹配成功都會去根據lastIndex去尋找下一個字元是否匹配,若沒有則lastIndex會被重設成0。

 

②.RegExp.prototype.exec(str)

使用Regex對字串執行搜尋,並將更新全域RegExp對象的屬性以反映匹配結果。如果沒有匹配的文本返回null,否則返回一個結果數組。

該結果數組中有兩個特別的對象屬性:

index:聲明匹配文本的第一個字元的位置,

input:存放匹配的字串

第一個元素是與Regex想匹配的文本

第二個元素是與RegExp對象的第一個子運算式想匹配的文本

第三個是與RegExp對象的第二個子運算式匹配的文本,以此類推

var reg1=/\d(\w)\d/;var reg2=/\d(\w)\d/g;var str=‘1a2b3c4d5e‘;reg1.exec(str) //["1a2", "a", index: 0, input:"1a2b3c4d5e"]reg2.exec(str)//["1a2", "a", index: 0, input: "1a2b3c4d5e"]

4.字串對象與正則相關的方法

①String.prototype.search(reg)

用於檢索字串中指定的子字串,或檢索與Regex相匹配的子字串

返回第一個匹配結果的index,若尋找不到則返回-1,

不執行全域匹配,忽略g標誌。

‘a1b2c3d1‘.search(/1/) //1‘a1b2c3d1‘.search(/1/g)  //1  忽略g標誌

②String.prototype.match(reg)

用於檢索字串,以找到一個或多個與regexp匹配的文本,是否具有g標誌對結果影響很大

非全域調用

只執行一次匹配,沒有找到匹配文本則返回null,否則返回一個數組,其中存放了與它找到匹配文本相關的資訊。

該結果數組中有兩個特別的對象屬性:

index:聲明匹配文本的第一個字元的位置,

input:存放匹配的字串

第一個元素是與Regex想匹配的文本

第二個元素是與RegExp對象的第一個子運算式想匹配的文本

第三個是與RegExp對象的第二個子運算式匹配的文本,以此類推

這與RegExp對象的exec方法很類似,只是字串與Regex的位子互換了。

全域調用

執行全域搜尋,找到字串中的所有匹配子字串,沒有找到返回null,否則返回一個數組,其中存放了與它找到匹配文本的相關資訊。

該結果數組中有兩個特別的對象屬性:

index:聲明匹配文本的第一個字元的位置,

input:存放匹配的字串

數組中的元素存放的是字串中所有的匹配到的子字串

③String.prototype.split(reg)

split方法是我們熟悉的方法,我們經常用split將一個字串分割成一個數組,同樣的這個分割符可以是一個Regex.

‘a1b2c3d‘.split(/\d/g)  //["a", "b", "c", "d"]

④.String.prototype.replace()

這個方法是特別重要也相對較複雜的方法,功能特彆強大的一個方法。

它有兩個參數,第一個參數是需要被替換的字串,第二個參數是用來替換的字串。

它有三種使用方法

String.prototype.replace(str,newStr),

String.prototype.replace(reg,newStr),

String.prototype.replace(reg,function)

重點就在於String.prototype.replace(reg,function)

function的傳回值是替換結果.這個function在每次匹配替換的時候被調用,有四個參數

1.匹配的字串

2.Regex分組內容,沒有分組則沒有該參數

3.匹配項在字串中的index

4.原字串

//沒有分組的情況
‘a1b2c3d4‘.replace(/\d/g,function(match,index,origin){ return parseInt(match)+1; })//"a2b3c4d5"
//有分組的情況
‘a1b2c3d4‘.replace(/(\d)(\w)(\d)/g,function(match,group1,group2,group3,index,origin){ return group1+group3;})//"a12c34"

以上就是Regex的大部分內容。Regex功能很強大,能熟練應用會給我們帶來很多便利。

JS之Regex

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.