[Javascript] Regular Expression 和如何Backrefrence

[Javascript] Regular Expression 和如何Backrefrence

前言

在有一天我在看藍色小鋪的時候,看到一個問題。這個問題是:「我如何取得JS Regx裡面match到括號內的資料?」這個問題不知道為甚麼,反正就是吸引了我,因此我做了一些調查,也順便當做是JS Regular Expression的學習。

在這篇,我會簡單介紹一下Js Regular Expression和如何取得括號內的資料。

JS 裡面的Regular Expression

創建一個RegExp

在Js,pattern的構成是由以下格式: /{pattern}/{flag} 例如: /hello/i

上面的意思是,我的Regular expression pattern是match 「hello」這個字串,同時後面的i是flag表示忽略大小寫。

在Js裡面,要實例一個Regular Expression的RegExp有兩種方式:

  1. 創建一個變數,而他的數值是Regular expression pattern格式:

    舉例來說: var pattern = /hello/i

  2. 創建一個new RegExp(pattern)

    例如: var reg = new RegExp(/hello/i)

上面兩種不同的創建方式的差異在於,假設今天你的pattern是由一個變數組成的(例如pattern是從一個Textbox取得的),那麼一定要使用第二種(new RegExp)。

使用RegExp去比對

RegExp提供了兩個Function,exec()和test()。這兩個的差異在於,exec()返回的是被match到的數值,而test()返回的是boolean表示是否有match成功。

不過,通常在String裡面有些也會用到RegExp,例如match()、search()、replace()和split()。而match和RegExp裡面的exec()是一樣的概念。

BackReference的概念

比較熟悉Regex的朋友知道,在Regex pattern裡面如果有括號,那麼被括號裡面match到的是可以在被取出來的,而這個稱之為backrefrence。

這個backrefrence可以有幾種方式使用:

  1. 在pattern裡面在次指向括號裡面match到的 - ()\n

    例如:

    
    		/(hello)\1/
    		
    同等於兩個hello
    
    	/hellohello/
    	

    數字1表示和第一個括號資料同等,2表示第二個......一直到n

  2. 當我們在做string.replace的時候

    例如,我們想把名字和姓顛倒,那麼:

    
    	var name = "John Smith".replace(/(John) (Smith)/, "$2 $1");
    	

    name現在等於"Smith John"。由此可以看出在Replace裡面使用的是$加上第幾個括號

  3. 當執行String.match(pattern)時,括號內的資料會被寫入RegExp.$1一直到$9(表示第9個) 例如:
    
    var string = '<a href="/board/AAAAA.html">1 < /a > ';
        pattern = /href="([^\'\"]+)/g;
        matches = string.match(pattern);
    
    alert(RegExp.$1);
    	
    	

    得到的是/board/AAAAA.html

當我們需要使用flag(/g)的時候,如何取得每一個的Backreference?

RegExp.$1記錄的是最後一次做Match的時候的Backreference。因此,當你的Regular expression有包括所有的match(使用flag /g)的時候,它記錄的就只是最後一次的Match。這個時候如果你要取得每一個match的Backreference,就會需要在做一個loop,然後每一個在Match一次:


var string = '<a href="/board/AAAAA.html">1 < /a ><img src="/images/title/icon_oar.gif" width="13" height="8"
vspace="2" /><a href="/board/BBBBB.html">2 < /a > <br / >';  
    pattern = /href="([^\'\"]+)/g;
    matches = string.match(pattern);

for(i=0; i< matches.length; i++)
{
  matches[i].match(pattern);
  console.log(RegExp.$1);
}

Reference

  1. 藍色小鋪的問題
  2. 介紹Backreference會對應到哪裡
  3. 中文介紹Javascript 的RegExp
  4. 介紹JS RegExp,同時有提到Backreference

Google+

創用 CC 授權條款
Alan Tsai 的隨手筆記Alan Tsai製作,以創用CC 姓名標示 4.0 國際 授權條款釋出。