正則表達式其實挺難的,對於新手來講就比如一本天書。不少高端大氣上檔次的教程啊教材啊博客啊通常都是先列出框框條條,再來細講,先元字符再量詞再分組再反向引用。我估計是國人都受到了國外教材的影響,由於這些東西是他們整出來的。對於他們來講思路是很清晰的。老手還好,勉強能吃透。新手你沒個幾十遍的功夫,門都找不到在哪裏。光那些規則,字母意思啊就夠你喝一壺的了,你是忘了看,看了忘。(ps:本文針對javascript正則)javascript
假如咱們根本就不知道有正則這玩意兒存在,要去匹配一個字母串咱們應該怎麼作了?讓咱們也作一回創造者吧html
當你輸入你的用戶名和密碼的時候,服務器君爲了給本身少點麻煩,就給瀏覽器君打了個電話說:你定的貨的參數可要對着了,哥的時間很寶貴。瀏覽器君坐不住了,立馬找來本身的小弟,權叫他正則君吧。你把這事給我辦一下,正則君但是倍感壓力啊,但是他也堅信世界上沒有過不去的坎,這不就是要我搞一些規則來檢查我輸入的字符串符不符合要求啊,就這樣正則君開始了它漫長而又艱辛的思考之路java
誰都不是傻蛋,都知道字符串通常都是有字母數字下劃線什麼的組成,變量命名不是都喜歡這麼整嘛。先入爲主,首先來檢測一個字母吧。26個英文字母不就是a-z,正則君不是牛頓君,固然也不能笨到用a來匹配a,b來匹配b....,那這種匹配就沒有意義了吧,畢竟你的輸入是變幻無窮的。須要的是以一敵十,以點破面。正則表達式
a或b或c...或z來匹配一個字母。若a沒匹配上就b上,b不行再c上···,一直下去,只要某個字母匹配上,就大功告成了。固然爲了減小書寫量,正則君把字母這一類整合了下,都是一路貨(或)色,就用個你們最多見的[]吧,範圍很明顯用-,就成了這樣[a-z]。長舒一口氣了,咱們總的試試個人思路對不對啊 ,整個test函數吧,其實就是簡單的if-else。瀏覽器
1 var reg=/[a-z]/; 2 var result=reg.test("d"); 3 alert(result);//true
就這樣一個字母搞定了,不對啊,字母不是還能夠大寫嗎,這個簡單,換成[A-Z]不就ok了。匹配字母簡單的綜合就是a-z或A-Z,放一起就是[a-zA-Z]。也就是你這個字母能夠是a或者b....或者A或者B...,一路或者。ruby
1 var reg=/[a-zA-Z]/; 2 var result=reg.test("A"); 3 alert(result);//true
一個字母搞定了,該數字了吧。那要是一串字母咋辦,仍是先把數字匹配了再說吧,0-9就是咱們的數字吧,仍是一路或下去吧(誰叫它是杰倫迷),0不行1上,1不行2上···只要某一個數字匹配上,就表示輸入合理。把上面字母類格式搬下來[0-9],試試效果:服務器
1 var reg=/[0-9]/; 2 var result=reg.test("3"); 3 alert(result);//true
這一不當心又彈出了true,正則君這內心開心的啊,先去喝個小酒整個小菜吧函數
酒足飯飽了,要是一串字母咋辦,一溜數字咋辦(本山大爺語錄,這可咋辦啊),前面不是說只要匹配成功一個就終止了,後面的咋辦了?多個字母不就是一個字母的不斷計數嘛,有幾個王八我抓幾個王八。正則君大手一揮,在後面加個計數器吧,就用{n}吧。[a-zA-Z]{3}。(ps:括號用的只剩下()了。就留着它幹一番大事業吧。)url
1 var reg=/[a-zA-Z]{3}/; 2 var result=reg.test("adc"); 3 alert(result);//true
1 var reg=/[a-zA-Z]{5}/; 2 var result=reg.test("adCef"); 3 alert(result);//true
一樣的,一串數字[0-9]{3}spa
1 var reg=/[0-9]{3}/; 2 var result=reg.test("123"); 3 alert(result);//true
要是這個串中有字母有數字咋整,這不就是或小寫字母或大寫字母或數字嗎?看[a-zA-Z0-9]表現如何
1 var reg=/[a-zA-Z0-9]{3}/; 2 var result=reg.test("a2z"); 3 alert(result);//true
一日瀏覽器君大鬧,我要的不是字母不是數字。正則君靈機一動[^a-zA-Z]匹配非字母。[^0-9]匹配非數字,天然[^a-zA-Z0-9]匹配非字母數字了.要要,切克鬧,字母數字都不要(煎餅果子來一套)。
固然咱們確定沒法限定你輸入字符串的長度了。所謂沙場上敵將數人,各懷絕技。QQ君勒立刻前,我但是有5位元老Q,還有12位的菜鳥Q。正則君呷了一口小酒喝道{5,12}通殺。銀行小職員輕聲道,金庫的銀子可很差數啊,+ 再殺,{n,}還殺。賭場君冷笑道你這是押大仍是押小,?走起。剎那間,正則是見招拆招。大戰多雄未賣一個破綻。後人將這些招式記載以下:
? | 出現零次或一次 |
* | 出現零次或屢次(任意次) |
+ | 出現一次或屢次(至道一次) |
{n} | 對應零次或者n次 |
{n,m} | 至少出現n次但不超過m次 |
{n,} | 至少出現n次(+的升級版) |
正則君在不斷的迎敵過程當中,也對本身的武功招式也作了一些總結,用本門心法收錄以下:
. | [^\n\r] | 除了換行和回車以外的任意字符 |
\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] | 非單詞字符 |
一個字母(數字)搞定了,一串字母(數字)也搞定了。自此以後正則君覺得江湖再無大事,今後高掛免戰牌。
不巧江湖最近出現了一個url地址君「http://www.ora.com:80/goodParts?fragment」,連破數名正則小弟。很多天鏖戰,正則君也敗下陣來,今後閉門苦研。誓斬地址君於馬下。裏面字母數字冒號?號,隊伍很龐大,招式很詭異。這麼多,咱們只有分散圍之,各個擊破,來他個圍點打援戰術如何。怎麼分隔,不是還有()沒用上嘛?
好了綜合一下試試看看能不能破了地址君:
1 var reg=/([A-Za-z]+:)(\/{2})([A-Za-z0-9\.]+)(:[\d+])(\/[^?]*)?(.*)/; 2 var result=reg.test("http://www.ora.com:80/goodParts?fragment"); 3 alert(result);//true
如今咱們要秋後算帳了,屈服於地址君淫威的某些正則君小弟被抓出來批鬥了。咱們須要把每一組匹配的東西單獨拿出來用啊,若是咱們想要把域名小弟揪出來。$3小手這麼一抖,看下面:
1 var reg=/([A-Za-z]+:)(\/{2})([A-Za-z0-9\.]+)(:[\d+])(\/[^?]*)?(.*)/; 2 var result=reg.test("http://www.ora.com:80/goodParts?fragment"); 3 alert(RegExp.$3);//www.ora.com
固然正則君也不是絕情之人,有些背叛本身的小弟是被逼無奈的就既往不咎了,咱們能夠把他們放在非捕獲性分組裏,給他的標號?:。我只看大家一眼,就不記在順天衙門的小冊子上了。看下面咱們放端口一馬吧,知道你是被逼無奈。
1 var reg=/([A-Za-z]+:)(?:\/{2})([A-Za-z0-9\.]+)(:[\d+])(\/[^?]*)?(.*)/; 2 var result=reg.test("http://www.ora.com:80/goodParts?fragment"); 3 alert(RegExp.$2);//www.ora.com
域名小弟這個倒黴玩意兒,怎麼又是你啊。看來分組小本上確實沒了端口君喲(非捕獲性分組不存放在匹配結果中,沒有組號)
此役以後,正則君在江湖上名聲大噪。江湖人稱正則表達式。他也不斷研習,一日看見了巴蛇吞象這個故事,靈感突發。正則君吞字符串,我如今牛了,我一口氣先吞下你,要是否是我要的那部分,就一節一節往外吐,此招式爲貪婪匹配。麪條一口一口吃,吃飽就好,就是非貪婪匹配?。。。。。江湖路依舊,淡看功與名。
小可不才,此文極度不嚴謹,爲初學者引路而已。此文原創,轉載請註明出處。若是你以爲文章還不錯,就推薦一下下吧!!!!
更多詳情參見此文:http://www.cnblogs.com/rubylouvre/archive/2010/03/09/1681222.html