日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

正則總結(jié):JavaScript中的正則表達(dá)式

 栲栗 2018-01-21

定義

在javascript我們可以通過(guò)內(nèi)建的類來(lái)定義一個(gè)正則表達(dá)式。

1var reName = new RegExp("nowamagic");

實(shí)際上RegExp類的構(gòu)造函數(shù)可以接受兩個(gè)參數(shù),除了本身需要匹配的模式字符串外,還可以定義指定額外處理方式的第二個(gè)參數(shù)。

1var reName = new RegExp("nowamagic","i");//忽略大小寫(xiě)

我很好奇輸出reName會(huì)得到什么結(jié)果呢?于是:

1document.write(reName);

得到結(jié)果:/nowamagic/i,于是我們得到j(luò)avascript中正則表達(dá)式的第二種定義方法(perl風(fēng)格):

1var reName = /nowamagic/;

那第二個(gè)參數(shù)呢?當(dāng)然,同樣可以為其指定第二個(gè)參數(shù):

1var reName = /nowamagic/i;

這兩種定義方式都是可行的,完全可以根據(jù)個(gè)人習(xí)慣進(jìn)行選擇。就像可以使用var s = new String(“for a simple life”);定義字符串的同時(shí)還可以使用var s = “for a simple life”;來(lái)定義是完全相同的。建議使用perl風(fēng)格的寫(xiě)法,除了簡(jiǎn)潔外,還省去了使用RegExp構(gòu)造函數(shù)定義時(shí)需要對(duì)“\”轉(zhuǎn)義的麻煩。

如果要匹配字符“\”,perl風(fēng)格的寫(xiě)法是:

1var res = /\\/;

而構(gòu)造函數(shù)的寫(xiě)法則需要對(duì)兩個(gè)“\”都進(jìn)行轉(zhuǎn)義:

1var res = new RegExp("\\\\");

感覺(jué)上是不是就麻煩了很多?

記住,在一個(gè)完整的正則表達(dá)式中“\”后面總是跟著另外一個(gè)字符。

javascript中的正則表達(dá)式

其實(shí)上面已經(jīng)在開(kāi)始講了javascript對(duì)正則表達(dá)式的實(shí)現(xiàn)方式了,只定義了正則表達(dá)式,但是如何在javascript中真正使用正則表達(dá)式呢?在javascript中RegExp和String對(duì)象都有處理正則表達(dá)式的方法。

  • test -- RegExp的test方法用來(lái)測(cè)試字符串是否匹配給出的匹配模式,返回布爾值;
  • exec -- RegExp的exec方法返回包含第一個(gè)匹配的的數(shù)組或null;
  • match -- String的match方法返回包含所有匹配子字符串的數(shù)組;
  • replace -- String的replace方法完成string的替換操作,支持正則表達(dá)式;
  • search -- 與String的indexof方法類似,不同的是search支持正則表達(dá)式,而不僅僅是字符串;
  • split -- 按照一定規(guī)則拆分字符串并將子字符串存儲(chǔ)到數(shù)組中的String方法。

關(guān)于這些函數(shù)的具體使用方法,可以參閱JS的相關(guān)函數(shù)手冊(cè)。

一個(gè)實(shí)例對(duì)象除了方法當(dāng)然還有屬性,一個(gè)正則表達(dá)式有以下屬性:

  • global -- 布爾值,若全局選項(xiàng)g已設(shè)置則返回true,否則返回false;
  • ignoreCase -- 布爾值,若忽略大小寫(xiě)選項(xiàng)i已設(shè)置則返回true,否則返回false;
  • lastIndex -- 整數(shù),使用exec或test方法時(shí)被填入,表示下次匹配將會(huì)從哪個(gè)字符位置開(kāi)始;
  • multiline -- 布爾值,表示多行模式選項(xiàng)m是否設(shè)置,若設(shè)置則返回true,否則返回false;
  • source -- 正則表達(dá)式的元字符串形式。/\\/的source將返回”\\“。

元字符

在正則表達(dá)式中有一些特殊的字符符號(hào)我們是不能直接使用的,必須對(duì)其進(jìn)行轉(zhuǎn)義后才能使用。如“\”,因?yàn)檫@些字符在正則表達(dá)式中有特殊的語(yǔ)法含義,這類字符被稱為元字符,正則表達(dá)式中的元字符有:

1.,\,/,*,?,+,[,(,),],{,},^,$,|

可能不太好記憶,當(dāng)無(wú)法確定某個(gè)字符是否是元字符的時(shí)候就勇敢的對(duì)其進(jìn)行轉(zhuǎn)義是沒(méi)有錯(cuò)的,對(duì)不是元字符的字符進(jìn)行轉(zhuǎn)義是不會(huì)出什么問(wèn)題的,但是如果不對(duì)元字符轉(zhuǎn)義就會(huì)有意想不到的錯(cuò)誤產(chǎn)生了。

分組匹配

一個(gè)簡(jiǎn)單的字符就可以是一個(gè)匹配模式,但是現(xiàn)實(shí)情況往往不會(huì)這么簡(jiǎn)單。比如我們要匹配一個(gè)0-9的數(shù)字:

1var i = 5;
2var j = 6;

這個(gè)正則表達(dá)式要如何書(shū)寫(xiě)才能同時(shí)匹配這兩個(gè)數(shù)字呢?簡(jiǎn)單的字符表達(dá)式當(dāng)然無(wú)法完成了,這個(gè)時(shí)候我們就可以為0-9十個(gè)數(shù)字來(lái)定義一個(gè)字符集合(字符類)來(lái)進(jìn)行匹配。

1var reNum = /[0123456789]/;
2document.write(reNum.test(i));//true
3document.write(reNum.test(j));//true

使用test方法測(cè)試匹配結(jié)果都輸出了true。

范圍匹配

上一個(gè)例子使用了分組匹配,但是如果要匹配所有26個(gè)英文字母,還要包括大小寫(xiě),仍然可以使用分組匹配:

1var reLetter = /abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/;

恩,這個(gè)正則表達(dá)式是完全正確的,但是是不是感覺(jué)太長(zhǎng)了,有沒(méi)有辦法讓它更為簡(jiǎn)潔一點(diǎn)?當(dāng)然是有的,為字符或數(shù)字指定一個(gè)匹配范圍就可以了。

1var reNum = /[0-9]/;
2var reLetter = /[a-zA-Z]/;

這樣就可以了,“-”用來(lái)定義一個(gè)匹配區(qū)間,字符的具體順序由ASCII字符表確定,所以不能寫(xiě)成/A-z/,因?yàn)閆-a之間還包含著其他字符。

取非匹配

很多編程語(yǔ)言中都使用“!”取非操作,包括javascript。正則表達(dá)式中也有取非操作,比如/[^0-9]/就是一個(gè)取非操作的正則表達(dá)式了。

1var i = 5;
2var s = "o";
3var rec = /[^0-9]/;
4document.write(rec.test(i));//false
5document.write(rec.test(s));//true

符號(hào)^用來(lái)完成取非操作,同時(shí)^0-9也是必須包含在[]中的,因?yàn)閊其實(shí)還有另外一種特殊用途。

特殊字符

可能你覺(jué)得/[a-zA-Z]/,/[0-9]/還是不夠簡(jiǎn)潔,的確,在正則表達(dá)式中一些特定的字符集合可以使用一些特殊的元字符來(lái)代替。這些特殊的字符并不是必不可少的,但是卻可以給我們帶來(lái)不少方便。/[0-9]/就完全可以寫(xiě)成這樣:

1var reNum = /\d/;

那大小寫(xiě)字母字符類呢?很遺憾,除了POSIX字符類(javascript不支持POSIX字符類)中有支持大小寫(xiě)字母的特殊字符類外并沒(méi)有專門替代方法。

常見(jiàn)的特殊字符有:

  • \d 任何一個(gè)數(shù)字字符,等價(jià)于[0-9]
  • \D 任何一個(gè)非數(shù)字字符,等價(jià)于[^0-9]
  • \w 任何一個(gè)字母數(shù)字或下劃線字符,等價(jià)于[a-zA-Z_]
  • \W 任何一個(gè)非字母數(shù)字和下劃線字符,等價(jià)于[^a-zA-Z_]
  • \s 任何一個(gè)空白字符,包括換頁(yè)符、換行符、回車符、制表符和垂直制表符,等價(jià)于[\f\n\r\t\v]
  • \S 任何一個(gè)非空白字符,等價(jià)于[^\f\n\r\t\v]
  • . 換行和回車以外的任何單個(gè)字符,等價(jià)于[^\n\r]

相同字母大小寫(xiě)總是進(jìn)行取非操作的。

十六進(jìn)制和八進(jìn)制字符

在正則表達(dá)式中使用十六進(jìn)制或八進(jìn)制字符也是完全可行的,他們所匹配的字符即是由其轉(zhuǎn)換成十進(jìn)制后的數(shù)值在ASCII中所對(duì)應(yīng)的字符。

1var reAt = /\x40/;//十六進(jìn)制字符\x40(64)對(duì)應(yīng)字符“@”
2var reA = /\0101/;//八進(jìn)制字符\0101(65)對(duì)應(yīng)字符“A”

重復(fù)匹配

以匹配一個(gè)email地址為例,mymail@mail.com這樣的一個(gè)email地址必須包括一個(gè)合法的用戶名mymail,@符號(hào)以及一個(gè)合法的域。其中用戶名和域名的字符個(gè)數(shù)都是無(wú)法判斷的,但是有一點(diǎn)是肯定的——用戶名必須至少是一個(gè)字符,域名至少是兩個(gè)字符中間還必須有一個(gè)點(diǎn)號(hào)。于是我們可以這樣做:

1var reMail = /\w+@\w+\.\w+/i;
2var email = "mymail@mail.com";
3document.write(reMail.test(email));//true

“+”表示字符出現(xiàn)一次或多次,至少出現(xiàn)一次。這個(gè)正則表達(dá)式其實(shí)并不能匹配所有合法的email地址,后面我們繼續(xù)完善。

除了“+”可以指定至少匹配一次外,還有很多其他的可以指定匹配次數(shù)的方式。

  • ? 出現(xiàn)零次或一次,最多一次
  • * 出現(xiàn)任意次(零次、一次、多次)
  • + 出現(xiàn)一次或多次,至少一次
  • {n} 能且只能出現(xiàn)n次
  • {n,m} 至少出現(xiàn)n次,最多出現(xiàn)m次

www.gogle.com,www.google.com,www.gooogle.com這三個(gè)網(wǎng)址都能正確地打開(kāi)google的首頁(yè),于是就可以用{n,m}匹配其中的1個(gè),2個(gè)或3個(gè)字母”o”。

1var gogle = "www.gogle.com";
2var google = "www.google.com";
3var gooogle = "www.gooogle.com";
4var reGoogle = /w{3}\.go{1,3}gle\.com/i;
5document.write(reGoogle.test(gogle));//true
6document.write(reGoogle.test(google));//true
7document.write(reGoogle.test(gooogle));//true

在上面的正則表達(dá)式中,我們使用了{(lán)3}來(lái)制定字符“w”能且只

能出現(xiàn)3次,用{1,3}來(lái)制定字母“o”可以出現(xiàn)1到3次。

防止過(guò)度匹配

有這樣一段HTML文本:

1var html = "<em>nowamagic</em>for a simple life<em>http:///</em>";

如果現(xiàn)在要講<em></em>及其中間的文本匹配出來(lái),正則表達(dá)式可以這樣寫(xiě):

1var reEm1 = /<em>.*<\/em>/gi;
2document.write(html.match(reEm1));//"<em>nowamagic</em>for a simple life<em>http:///</em>"
3var reEm2 = /<em>.*?<\/em>/gi;
4document.write(html.match(reEm2));//<em>nowamagic</em>,<em>http:///</em>

當(dāng)使用貪婪模式的時(shí)候,”.*”會(huì)最大程度地進(jìn)行字符匹配,所以輸出了整個(gè)字符串。而在惰性模式中,”.*?”只進(jìn)行最小限度的匹配,所以完整的輸出了我們需要的字符串。

惰性模式的語(yǔ)法很簡(jiǎn)單,即是在貪婪模式后面加上一個(gè)“?”即可。

  • * –> *?
  • + –> +?
  • {n,} –> {n,}?

位置匹配

1var s = “_Don’t do it!”;

如何將單詞“do”匹配出來(lái)?it’s easy!

1var reDo = /do/gi;
2document.write(s.match(reDo));//Do,do

但是這個(gè)簡(jiǎn)單的正則表達(dá)式/do/gi將“don’t”中的“do”也進(jìn)行了匹配,可這并不是想要的結(jié)果。而在正則表達(dá)式中有專門用來(lái)進(jìn)行單詞邊界匹配的限定符”\b“。

1var reDo = /\bdo\b/gi;
2document.write(s.match(reDo));//do

“\b”到底匹配的什么呢?”\b”匹配的是一個(gè)位置,一個(gè)位于”\w“(字母,數(shù)字,下劃線)和”\W“之間的位置。

既然有”\b”,那有”\B”嗎?當(dāng)然,他和”\b“剛好相反,由來(lái)匹配一個(gè)不是單詞邊界的位置。比如上例中匹配”don’t”中的”do”時(shí)”\B”就可派上用場(chǎng)。

1var reDo = /\Bdo\B/gi;
2document.write(s.match(reDo));//Do

在介紹取非匹配的時(shí)候介紹^只用位于[]并緊跟[方能取非匹配,而^還有另外一種用途——字符串邊界匹配。

  • ^ 用來(lái)匹配字符串開(kāi)頭
  • $ 用來(lái)匹配字符串結(jié)尾

比如我們要匹配一個(gè)http://形式的net域名:

1var url = "http://";
2var reUrl = /^(http):\/\/nowamagic\.(net)$/gi;
3document.write(reUrl.test(url));//true

正則表達(dá)式reUrl限制url必須以”http”開(kāi)頭,以”net”結(jié)尾。

又如經(jīng)常被擴(kuò)展的string方法trim:

1function trim(s){
2  return s.replace(/(^\s*)|(\s*$)/g,"");
3}

同時(shí)我們可以在整個(gè)模式的最前面使用(?m)來(lái)啟用分行匹配模式。這樣,^不但匹配正常的字符串開(kāi)頭,還將匹配行分隔符(換行符)后面的開(kāi)始位置;$不僅匹配正常的字符串結(jié)尾,還將匹配行分隔符(換行符)后面的結(jié)束位置。

延伸閱讀

此文章所在專題列表如下:

  1. 什么是正則表達(dá)式?
  2. 正則入門:匹配固定的單個(gè)字符
  3. 正則入門:匹配任意的單個(gè)字符
  4. 正則入門:字符組的使用
  5. 正則入門:在字符組中使用字符區(qū)間
  6. 正則入門:反義字符組的使用
  7. 正則入門:匹配空字符
  8. 正則入門:匹配一個(gè)或多個(gè)字符
  9. 正則入門:匹配零個(gè)或多個(gè)字符
  10. 正則入門:匹配零個(gè)或一個(gè)字符串
  11. 正則入門:匹配固定數(shù)目的字符
  12. 正則入門:匹配區(qū)間內(nèi)數(shù)目的字符
  13. 正則入門:貪婪匹配
  14. 正則入門:惰性匹配
  15. 正則入門:兩個(gè)匹配模式
  16. 正則入門:匹配單詞邊界
  17. 正則入門:邊界的定義與相對(duì)性
  18. 正則入門:匹配非單詞邊界
  19. 正則入門:匹配文本首和尾
  20. 正則入門:子模式
  21. 正則入門:“或”匹配
  22. 正則入門:后向引用文本替換
  23. 正則入門:非獲取匹配
  24. 正則總結(jié):JavaScript中的正則表達(dá)式
  25. 正則總結(jié):正則表達(dá)式在js中的高級(jí)應(yīng)用

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多