JavaScriptRegex符號詳解

來源:互聯網
上載者:User
文章目錄
  • c{n}
  • c{m,n}
  • c{n,}
  • *,+,?
  • 貪心與非貪心
  • 不記錄子Regex的匹配結果
  • 正向預查
  • ?!
  • 全域匹配,修飾符g
  • 不區分大小寫,修飾符i
  • 行首行尾,修飾符m
  • exec方法的傳回值
  • exec方法對Regex的更新
  • match方法
  • replace方法
  • search方法和split方法

第一種方法:

var reg = /pattern/;

第二種方法:

var reg = new RegExp('pattern');

Regex的exec方法簡介

文法:

reg.exec(str);

其中str為要執行Regex的目標字串。

例如:

<script type="text/java script"> var reg = /test/; var str = 'testString'; var result = reg.exec(str); alert(result); </script>

將會輸出test,因為Regexreg會匹配str(‘testString’)中的’test’子字串,並且將其返回。

我們使用下面的函數來做匹配正則的練習:

function execReg(reg,str){ var result = reg.exec(str); alert(result); }

函數接受一個Regex參數reg和一個目標字串參數str,執行之後會alert出Regex與字串的匹配結果。

用這個函數測試上面的例子就是:

<script type="text/java script"> function execReg(reg,str){ var result = reg.exec(str); alert(result); } var reg = /test/; var str = 'testString'; execReg(reg,str); </script>

上面的例子用正則裡的test去匹配字串裡的test,實在是很無聊,同樣的任務用indexOf方法就可以完成了。用正則,自然是要完成更強大的功能:

一片兩片三四片,落盡正則全不見

上面的小標題翻譯成正則就是{1},{2},{3,4},{1,}。

c{n}

{1}表示一個的意思。

/c{1}/只能匹配一個c。

/c{2}/則會匹配兩個連續的c。

以此類推,

/c{n}/則會匹配n個連續的c。

看下面的例子:

reg = /c{1}/; str='cainiao'; execReg(reg,str);

返回結果c

reg = /c{2}/; str='cainiao'; execReg(reg,str);

返回結果null,表示沒有匹配成功。

reg = /c{2}/; str='ccVC果凍爽'; execReg(reg,str);

返回結果cc。

c{m,n}

c{3,4}的意思是,連續的3個c或者4個c。

例如

reg = /c{3,4}/; str='ccVC果凍爽'; execReg(reg,str);

返回結果null,表示沒有匹配成功。

reg = /c{3,4}/; str='cccTest'; execReg(reg,str);

結果返回ccc。

reg = /c{3,4}/; str='ccccTest'; execReg(reg,str);

結果返回cccc,這表明正則會盡量多品牌,可3可4的時候它會選擇多匹配一個。

reg = /c{3,4}/; str='cccccTest'; execReg(reg,str);

仍然只匹配4個c。

由以上例子可以推斷出,c{m,n}表示m個到n個c,且m小於等於n。

c{n,}

c{1,}表示1個以上的c。例如:

reg = /c{1,}/; str='cainiao'; execReg(reg,str);

結果返回c。

reg = /c{1,}/; str='cccccTest'; execReg(reg,str);

返回ccccc,再次說明了Regex會盡量多地匹配。

reg = /c{2,}/; str='cainiao'; execReg(reg,str);

結果返回null,c{2,}表示2個以上的c,而cainiao中只有1個c。

由以上例子可知,c{n,}表示最少n個c,最多則不限個數。

*,+,?

*表示0次或者多次,等同於{0,},即

c* 和 c{0,} 是一個意思。

+表示一次或者多次,等同於{1,},即

c+ 和 c{1,} 是一個意思。

最後,?表示0次或者1次,等同於{0,1},即

c? 和 c{0,1} 是一個意思。

貪心與非貪心

人都是貪婪的,正則也是如此。我們在例子reg = /c{3,4}/;str='ccccTest';的例子中已經看到了,能匹配四個的時候,正則絕對不會去匹配三個。上面所介紹的所有的正則都是這樣,只要在合法的情況下,它們會盡量多去匹配字元,這就叫做貪心模式。

如果我們希望正則盡量少地匹配字元,那麼就可以在表示數位符號後面加上一個?。組成如下的形式:

{n,}?, *?, +?, ??, {m,n}?

同樣來看一個例子:

reg = /c{1,}?/; str='ccccc'; execReg(reg,str);

返回的結果只有1個c,儘管有5個c可以匹配,但是由於Regex是非貪心模式,所以只會匹配一個。

/^開頭,結尾$/

^表示只匹配字串的開頭。看下面的例子:

reg = /^c/; str='維生素c'; execReg(reg,str);

結果為null,因為字串‘維生素c’的開頭並不是c,所以匹配失敗。

reg = /^c/; str='cainiao'; execReg(reg,str);

這次則返回c,匹配成功,因為cainiao恰恰是以c開頭的。

與^相反,$則只匹配字串結尾的字元,同樣,看例子:

reg = /c$/; str='cainiao'; execReg(reg,str);

返回null,表示Regex沒能在字串的結尾找到c這個字元。

reg = /c$/; str='維生素c'; execReg(reg,str);

這次返回的結果是c,表明匹配成功。

點’.’

‘.’會匹配字串中除了分行符號/n之外的所有字元,例如

reg = /./; str='cainiao'; execReg(reg,str);

結果顯示,正則匹配到了字元c。

reg = /./; str='blueidea'; execReg(reg,str);

這次是b。

reg = /.+/; str='blueidea——經典論壇 好_。'; execReg(reg,str);

結果是“blueidea——經典論壇 好_。“也就是說所有的字元都被匹配掉了,包括一個空格,一個下滑線,和一個破折號。

reg = /.+/; reg = /.+/; str='bbs.blueidea.com'; execReg(reg,str);

同樣,直接返回整個字串——bbs.blueidea.com,可見”.”也匹配”.”本身。

reg = /^./; str='/ncainiao'; execReg(reg,str);

結果是null,終於失敗了,正則要求字串的第一個字元不是換行,但是恰恰字元是以/n開始的。

二選一,Regex中的或,“|“

b|c表示,匹配b或者c。

例如:

reg = /b|c/; str='blueidea'; execReg(reg,str);

結果是b。

reg = /b|c/; str='cainiao'; execReg(reg,str);

結果是c。

reg = /^b|c.+/; str='cainiao'; execReg(reg,str);

匹配掉整個cainiao。

reg = /^b|c.+/; str='bbs.blueidea.com'; execReg(reg,str);

結果只有一個b,而不是整個字串。因為上面Regex的意思是,匹配開頭的b或者是c.+。

括弧

reg = /^(b|c).+/; str='bbs.blueidea.com'; execReg(reg,str);

這次的結果是整個串bbs.blueidea.com,機上上面的括弧這後,這個正則的意思是,如果字串的開頭是b或者c,那麼匹配開頭的b或者c以及其後的所有的非換行字元。

如果你也實驗了的話,會發現返回的結果後面多出來一個“,b“,這是()內的b|c所匹配的內容。我們在Regex內括弧裡寫的內容會被認為是子Regex,所匹配的結果也會被記錄下來供後面使用。我們暫且不去理會這個特性。

字元集合[abc]

[abc]表示a或者b或者c中的任意一個字元。例如:

reg = /^[abc]/; str='bbs.blueidea.com'; execReg(reg,str);

返回結果是b。

reg = /^[abc]/; str='test'; execReg(reg,str);

這次的結果就是null了。

我們在字字元集合中使用如下的表示方式:[a-z],[A-Z],[0-9],分別表示小寫字母,大寫字母,數字。例如:

reg = /^[a-zA-Z][a-zA-Z0-9_]+/; str='test'; execReg(reg,str);

結果是整個test,正則的意思是開頭必須是英文字母,後面可以是英文字母或者數字以及底線。

反字元集合[^abc]

^在Regex開始部分的時候表示開頭的意思,例如/^c/表示開頭是c;但是在字元集和中,它表示的是類似“非“的意思,例如[^abc]就表示不能是a,b或者c中的任何一個。例如:

reg = /[^abc]/; str='blueidea'; execReg(reg,str);

返回的結果是l,因為它是第一個非abc的字元(即第一個b沒有匹配)。同樣:

reg = /[^abc]/; str='cainiao'; execReg(reg,str);

則返回i,前兩個字元都是[abc]集合中的。

由此我們可知:[^0-9]表示非數字,[^a-z]表示非小寫字母,一次類推。

邊界與非邊界

/b表示的邊界的意思,也就是說,只有字串的開頭和結尾才算數。例如//bc/就表示字串開始的c或者是結尾的c。看下面的例子:

reg = //bc/; str='cainiao'; execReg(reg,str);

返回結果c。匹配到了左邊界的c字元。

reg = //bc/; str='維生素c'; execReg(reg,str);

仍然返回c,不過這次返回的是右側邊界的c。

reg = //bc/; str='bcb'; execReg(reg,str);

這次匹配失敗,因為bcb字串中的c被夾在中間,既不在左邊界也不再右邊界。

與/b對應/B表示非邊界。例如:

reg = //Bc/; str='bcb'; execReg(reg,str);

這次會成功地匹配到bcb中的c,。然而

reg = //Bc/; str='cainiao'; execReg(reg,str);

則會返回null。因為/B告訴正則,只匹配非邊界的c。

數字與非數字

/d表示數位意思,相反,/D表示非數字。例如:

reg = //d/; str='cainiao8'; execReg(reg,str);

返回的匹配結果為8,因為它是第一個數字字元。

reg = //D/; str='cainiao8'; execReg(reg,str);

返回c,第一個非數字字元。

空白

/f匹配換頁符,/n匹配分行符號,/r匹配斷行符號,/t匹配製表符,/v匹配垂直定位字元。

/s匹配單個空格,等同於[/f/n/r/t/v]。例如:

reg = //s.+/; str='This is a test String.'; execReg(reg,str);

返回“is a test String.”,正則的意思是匹配第一個空格以及其後的所有非換行字元。

同樣,/S表示非空白字元。

reg = //S+/; str='This is a test String.'; execReg(reg,str);

匹配結果為This,當遇到第一個空格之後,正則就停止匹配了。

單詞字元

/w表示單詞字元,等同於字元集合[a-zA-Z0-9_]。例如:

reg = //w+/; str='blueidea'; execReg(reg,str);

返回完整的blueidea字串,因為所有字元都是單詞字元。

reg = //w+/; str='.className'; execReg(reg,str);

結果顯示匹配了字串中的className,只有第一個“.”——唯一的非單詞字元沒有匹配。

reg = //w+/; str='中文如何?'; execReg(reg,str);

試圖用單詞字元去匹配中文自然行不通了,返回null。

/W表示非單詞字元,等效於[^a-zA-Z0-9_]

reg = //W+/; str='中文如何?'; execReg(reg,str);

返回完整的字串,因為,無論是中文和“?”都算作是非單詞字元。

反向引用

形式如下:/(子Regex)/1/

依舊用例子來說明:

1.

reg = //w/; str='blueidea'; execReg(reg,str);

返回b。

2.

reg = /(/w)(/w)/; str='blueidea'; execReg(reg,str);

返回bl,b,l

bl是整個正則匹配的內容,b是第一個括弧裡的子Regex匹配的內容,l是第二個括弧匹配的內容。

3.

reg = /(/w)/1/; str='blueidea'; execReg(reg,str);

則會返回null。這裡的“/1”就叫做反向引用,它表示的是第一個括弧內的字Regex匹配的內容。在上面的例子中,第一個括弧裡的(/w)匹配了b,因此“/1”就同樣表示b了,在餘下的字串裡自然找不到b了。

與第二個例子對比就可以發現,“/1”是等同於“第1個括弧匹配的內容”,而不是“第一個括弧的內容”。

reg = /(/w)/1/; str='bbs.blueidea.com'; execReg(reg,str);

這個正則則會匹配到bb。

同樣,前面有幾個子Regex我們就可以使用幾個反向引用。例如:

reg = /(/w)(/w)/2/1/; str='woow'; execReg(reg,str);

會匹配成功,因為第一個括弧匹配到w,第二個括弧匹配到o,而/2/1則表示ow,恰好匹配了字串的最後兩個字元。

括弧(2)

前面我們曾經討論過一次括弧的問題,見下面這個例子:

reg = /^(b|c).+/; str='bbs.blueidea.com'; execReg(reg,str);

這個正則是為了實現只匹配以b或者c開頭的字串,一直匹配到換行字元,但是。上面我們已經看到了,可以使用“/1”來反向引用這個括弧裡的子Regex所匹配的內容。而且exec方法也會將這個字Regex的匹配結果儲存到返回的結果中。

不記錄子Regex的匹配結果

使用形如(?:pattern)的正則就可以避免儲存括弧內的匹配結果。例如:

reg = /^(?:b|c).+/; str='bbs.blueidea.com'; execReg(reg,str);

可以看到返回的結果不再包括那個括弧內的字Regex多匹配的內容。

同理,反向引用也不好使了:

reg = /^(b|c)/1/; str='bbs.blueidea.com'; execReg(reg,str);

返回bb,b。bb是整個Regex匹配的內容,而b是第一個子Regex匹配的內容。

reg = /^(?:b|c)/1/; str='bbs.blueidea.com'; execReg(reg,str);

返回null。由於根本就沒有記錄括弧內匹配的內容,自然沒有辦法反向引用了。

正向預查

形式:(?=pattern)

所謂正向預查,意思就是:要匹配的字串,後面必須緊跟著pattern!

我們知道Regex/cainiao/會匹配cainiao。同樣,也會匹配cainiao9中的cainiao。但是我們可能希望,cainiao只能匹配cainiao8中的菜鳥。這時候就可以像下面這樣寫:/cainiao(?=8)/,看兩個執行個體:

reg = /cainiao(?=8)/; str='cainiao9'; execReg(reg,str);

返回null。

reg = /cainiao(?=8)/; str='cainiao8'; execReg(reg,str);

匹配cainiao。

需要注意的是,括弧裡的內容並不參與真正的匹配,只是檢查一下後面的字元是否符合要求而已,例如上面的正則,返回的是cainiao,而不是cainiao8。

再來看兩個例子:

reg = /blue(?=idea)/; str='blueidea'; execReg(reg,str);

匹配到blue,而不是blueidea。

reg = /blue(?=idea)/; str='bluetooth'; execReg(reg,str);

返回null,因為blue後面不是idea。

reg = /blue(?=idea)/; str='bluetoothidea'; execReg(reg,str);

同樣返回null。

?!

形式(?!pattern)和?=恰好相反,要求字串的後面不能緊跟著某個pattern,還拿上面的例子:

reg = /blue(?!idea)/; str='blueidea'; execReg(reg,str);

返回null,因為正則要求,blue的後面不能是idea。

reg = /blue(?!idea)/; str='bluetooth'; execReg(reg,str);

則成功返回blue。

匹配元字元

首先要搞清楚什麼是元字元呢?我們之前用過*,+,?之類的符號,它們在Regex中都有一定的特殊含義,類似這些有特殊功能的字元都叫做元字元。例如

reg = /c*/;

表示有任意個c,但是如果我們真的想匹配’c*’這個字串的時候怎麼辦呢?只要將*轉義了就可以了,如下:

reg = /c/*/; str='c*'; execReg(reg,str);

返回匹配的字串:c*。

同理,要匹配其他元字元,只要在前面加上一個“/”就可以了。

Regex的修飾符全域匹配,修飾符g

形式:/pattern/g

例子:reg = /b/g;

後面再說這個g的作用。先看後面的兩個修飾符。

不區分大小寫,修飾符i

形式:/pattern/i

例子:

var reg = /b/; var str = 'BBS'; execReg(reg,str);

返回null,因為大小寫不符合。

var reg = /b/i; var str = 'BBS'; execReg(reg,str);

匹配到B,這個就是i修飾符的作用了。

行首行尾,修飾符m

形式:/pattern/m

m修飾符的作用是修改^和$在Regex中的作用,讓它們分別表示行首和行尾。例如:

var reg = /^b/; var str = 'test/nbbs'; execReg(reg,str);

匹配失敗,因為字串的開頭沒有b字元。但是加上m修飾符之後:

var reg = /^b/m; var str = 'test/nbbs'; execReg(reg,str);

匹配到b,因為加了m修飾符之後,^已經表示行首,由於bbs在字串第二行的行首,所以可以成功地匹配。

exec方法詳解exec方法的傳回值

exec方法返回的其實並不是匹配結果字串,而是一個對象,簡單地修改一下execReg函數,來做一個實驗就可以印證這一點:

function execReg(reg,str){ var result = reg.exec(str); alert(typeof result); } var reg = /b/; var str='bbs.bblueidea.com'; execReg(reg,str);

結果顯示result的類型是object。而且是一個類似數組的對象。使用for in可以知道它的屬性: index input 0。其中index是表示匹配在原字串中的索引;而input則是表示輸入的字串;

至於0則是表示只有一個匹配結果,可以用下標0來引用這個匹配結果,這個數量可能改變。我們可以通過傳回值的length屬性來得知匹配結果的總數量。

根據以上對傳回值的分析,修改execReg函數如下:

function execReg(reg,str){ var result = reg.exec(str); document.write('index:'+result.index+'<br />' +'input:'+result.input+'<br />' ); for(i=0;i<result.length;i++){ document.write('result['+i+']:'+result[i]+'<br />') } }

馬上來實驗一下:

var reg = //w/; var str='bbs.bblueidea.com'; execReg(reg,str);

結果如下:

  • index:0
  • input:bbs.bblueidea.com
  • result[0]:b

輸入字串為bbs.bblueidea.com;

匹配的b在原字串的索引是0。

正則的匹配結果為一個,b;

var reg = /(/w)(/w)(.+)/; var str='bbs.bblueidea.com'; execReg(reg,str);

結果為:

index:0
input:bbs.bblueidea.com
result[0]:bbs.bblueidea.com
result[1]:b
result[2]:b
result[3]:s.bblueidea.com

由上面兩個例子可見,返回對象[0]就是整個Regex所匹配的內容。後續的元素則是各個子Regex的匹配內容。

exec方法對Regex的更新

exec方法在返回結果對象的同時,還可能會更新原來的Regex,這就要看Regex是否設定了g修飾符。先來看兩個例子吧:

var reg = /b/; var str = 'bbs.blueidea.com'; execReg(reg,str); execReg(reg,str);

結果如下:

index:0
input:bbs.blueidea.com
result[0]:b
index:0
input:bbs.blueidea.com
result[0]:b

也就是說,兩次匹配的結果完全一樣,從索引可以看出來,匹配的都是字串首的b字元。

下面看看設定了g的Regex表現如何:

var reg = /b/g; var str = 'bbs.blueidea.com'; execReg(reg,str); execReg(reg,str);

結果如下:

index:0
input:bbs.blueidea.com
result[0]:b
index:1
input:bbs.blueidea.com
result[0]:b

可以看得出來,第二次匹配的是字串的字串的第二個b。這也就是g修飾符的作用了,下面來看exec是如何區別對待g和非gRegex的。

如果Regex沒有設定g,那麼exec方法不會對Regex有任何的影響,如果設定了g,那麼exec執行之後會更新Regex的lastIndex屬性,表示本次匹配後,所匹配字串的下一個字元的索引,下一次再用這個Regex匹配字串的時候就會從上次的lastIndex屬性開始匹配,也就是上面兩個例子結果不同的原因了。

test方法

test方法僅僅檢查是否能夠匹配str,並且返回布爾值以表示是否成功。同樣建立一個簡單的測試函數:

function testReg(reg,str){ alert(reg.test(str)); }

執行個體1

var reg = /b/; var str = 'bbs.blueidea.com'; testReg(reg,str);

成功,輸出true。

執行個體2

var reg = /9/; var str = 'bbs.blueidea.com'; testReg(reg,str);

失敗,返回false。

使用字串的方法執行Regexmatch方法

形式:str.match(reg);

與Regex的exec方法類似,該方法同樣返回一個類似數組的對象,也有input和index屬性。我們定義如下一個函數用來測試:

function matchReg(reg,str){ var result = str.match(reg); if(result ){ document.write('index:'+result.index+'<br />' +'input:'+result.input+'<br />' ); for(i=0;i<result.length;i++){ document.write('result['+i+']:'+result[i]+'<br />') } }else{ alert('null:匹配失敗!') } }

例如:

var reg = /b/; var str = 'bbs.blueidea.com'; matchReg(reg,str);

結果如下:

index:0
input:bbs.blueidea.com
result[0]:b

可見,和exec的結果一樣。

但是如果Regex設定了g修飾符,exec和match的行為可就不一樣了,見下例:

index:undefined
input:undefined
result[0]:b
result[1]:b
result[2]:b

設定了g修飾符的Regex在完成一次成功匹配後不會停止,而是繼續找到所有可以匹配到的字元。返回的結果包括了三個b。不過沒有提供input和index這些資訊。

replace方法

形式:str. replace (reg,’new str’);

它的作用是將str字串中匹配reg的部分用’’new str”部分代碼,值得注意的是原字串並不會被修改,而是作為傳回值被返回。例子:

var reg = /b/; var str = 'bbs.blueidea.com'; var newStr = str.replace(reg,'c'); document.write(newStr);

結果為cbs.blueidea.com,只有第一個b被替換為c。

var reg = /b/g; var str = 'bbs.blueidea.com'; var newStr = str.replace(reg,'c'); document.write(newStr);

輸出ccs.clueidea.com

由於,設定了g修飾符,所以會替換掉所有的b。

var reg = //w+/g; var str = 'bbs.blueidea.com'; var newStr = str.replace(reg,'word'); document.write(newStr);

輸出:

word.word.word。

在replace函數中使用$引用子Regex匹配內容

就像在正則裡我們可以使用/1來引用第一個子Regex所匹配的內容一樣,我們在replace函數的替換字元裡也可以使用$1來引用相同的內容。

還是來看一個例子吧:

var reg = /(/w+).(/w+).(/w+)/; var str = 'bbs.blueidea.com'; var newStr = str.replace(reg,'$1.$1.$1'); document.write(newStr);

輸出的結果為:

bbs.bbs.bbs

首先,我們知道第一個子Regex匹配到了bbs,那麼$1也就代表bbs了。其後我們把替換字串設定為'$1.$1.$1',其實也就是“bbs.bbs.bbs”。同理,$2就是blueidea,$3就是com。

在來看一個例子,顛倒空格前後兩個單詞的順序。

var reg = /(/w+)/s(/w+)/; var str = 'cainiao gaoshou'; var newStr = str.replace(reg,'$2 $1'); document.write(newStr);

結果為:gaoshou cainiao,也就是空格前後的單詞被調換順序了。

由於在替換文本裡$有了特殊的含義,所以我們如果想要是用$這個字元的話,需要寫成$$,例如:

var reg = /(/w+)/s(/w+)/; var str = 'cainiao gaoshou'; var newStr = str.replace(reg,'$$ $$'); document.write(newStr);

結果為:$ $。

search方法和split方法

同樣,字串的search方法和split方法中也可以使用Regex,形式如下:

str.search(reg);

search返回Regex第一次匹配的位置。例子:

var reg = /idea/; var str = 'blueidea'; var pos = str.search(reg); document.write(pos);

結果為4。

下面的例子找出第一個非單詞字元:

var reg = //W/; var str = 'bbs.blueidea.com'; var pos = str.search(reg); document.write(pos);

結果為3,也就是那個點“.”的位置。

str.split(reg,’seprator’); split返回分割後的數組,例如: var reg = //W/; var str = 'bbs.blueidea.com'; var arr = str.split(reg); document.write(arr);

結果為:bbs,blueidea,com,可見數組被非單詞字元分為了有三個元素的數組。

var reg = //W/; var str = 'http://www.baidu.com/'; var arr = str.split(reg); document.write(arr.length+'<br />'); document.write(arr);

結果為:

7
http,,,www,baidu,com,

可見字串被分為了有7個元素的數組,其中包括了三個為空白字串的元素。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.