DIV CSS 佈局教程網

JS 正則表達式
編輯:JavaScript基礎知識     
【JS復習筆記】05 正則表達式

好吧,正則表達式,我從來沒記過。以前要用的時候都是網上Copy一下的。

這裡還是扯一下吧,以後要是有要用到的正則表達式那麼就收集到這個帖子裡。(盡管我認為不會,因為我根本就不是一個專業的前端,我只是來劃下水的\(^o^)/)

應用范圍:正則表達式主要應用於對字符串中的信息實現查找,替換和提取操作。

可處理正則表達式的方法有6個:

regexp.exec,regexp.test,string.match,string.replace,string.search和string.split

應用原因:在JS中,正則表達式相對於等效的字符串處理來說,有著顯著的性能優勢。

缺點:正如大部分人所看到的,這個東西有的時候光是看起來就很復雜和難懂。起碼你讓我這種菜去維護一個正則表達式我在網上Copy不到,一般都會用非正則表達式的方式去處理,美其名曰:代碼可讀性!

JS中正則表達式必需寫在一行中,空白需要特別注意。

下面上一段代碼:

var myRegExp=/^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var url="http://hovertree.com:8041/goodparts?q#fragment";
var result=myRegExp.exec(url);

看到上面這段代碼你知道什麼意思嗎,絕大多數人不知道,知道的人也要看半天。這就是為什麼大家都不願意寫這玩意。好了,這章就這樣吧,大家散了吧。

即使如此,我還是自己要寫下去,因為他實現的效果是這樣的:

result的結果是下面這個數組:

["http://hovertree.com:8041/goodparts?q#fragment", "http", "//", "hovertree.com", "8041", "goodparts", "q", "fragment"]

這就是我為什麼繼續寫下去的原因所在。

好吧,讓我們一起學學這蛋疼又犀利的語法吧:

  • ^     表示字符串以下面匹配的方式開始
  • (?:([A-Za-z]+):)?   這個是套著捕獲分組1的非捕獲分組,必須後面跟著一個冒號才匹配(記住這裡的冒號才匹配是由後面那個冒號決定的),匹配一個協議名,也就是http。
    • (?:)   表示一個非捕獲型分組
    • 後綴? 表示這個分組是可選的,他表示重復0次或者一次。就比如你輸入的url為www.baidu.com,不帶協議名也是可以匹配的。
    • (...)   表示一個捕獲型分組。一個捕獲型分組會復制它所匹配的文本,並將其放在result數組裡。每個捕獲分組都會被指定一個編號。第一個捕獲分組的編號是1,所以result[1]表示它。result[0]就是原字符串。
    • [...]   表示一個字符類。A-Za-z其實很好理解,就是26個大寫字母和26個小寫字母。-代表范圍。
    • 後綴+ 表示這個字符類會被匹配一次或者多次。
    • 後面那個: 它表示匹配的字符串必須後面跟著一個冒號
  •   (\/{0,3})   這個是捕獲分組2,這個因子匹配的是兩個左斜槓
    • \/     表示的就是一個/,可以理解為\n一樣的轉義字符。
    • {0,3} 表示/這個東西會被匹配0到3次
  • ([0-9.\-A-Za-z]+) 這個是捕獲分組3,匹配一個www.baidu.com之類的東西,由一個或多個字母和數字,以及 . 和 - 兩個字符組成。也就是說你的網址是www.baidu.....----com---也是正確的
  • (?::(\d+)?  這個是套著捕獲分組4的非捕獲分組,匹配的是端口號。也就是以:開頭的數字。同事將這個數字捕獲後放入結果數組  
    • \d 表示的是一個數字字符,[0-9]也可以實現一樣的效果
  • (?:\/([^?#]*))?   這又是一個套著捕獲分組5的非捕獲分組,它捕獲了goodparts
    • (?:\/(...))? 匹配以左斜槓/開頭的字串0到1次
    • [^?#]    匹配非?和#的所有字符,^表示非的意思
    • 後綴*  表示被匹配0次或者多次,和後綴+差不多,不過+是從1開始,
  • (?:\?([^#]*))? 同上吧,類似的,自己應該可以理解了吧
  • (?:#(.*))?  大致同上,
    • .  會匹配除行結束符以外的所有字符
  • $   表示字符串以上面那些匹配的方式結束

老實說,我照著書看完,又把這些話歸納總結出來,然後我就一直在想一個問題。

到底我是什麼時候覺得正則表達式很難的呢?

是我還超級菜,並且還不愛學的時候。看什麼都覺得難,再加上人也浮躁,不想沉下心來去學,所以形成了一個這樣的印象。如今看來真是簡單至極。

我會告訴你我基本上就從來沒有自己寫過正則表達式嗎,我只會copy。

但是我在剛剛一個小時的學習中,我覺得我可以了,而且我能立馬寫出一段很6的正則表達式,無論多長,只需要把每個捕獲分組換一行寫就行了,然後貼到代碼裡時再合成一行。

突然的感悟:程序員只是需要一個安靜的心和學習的興趣。

我不會告訴你我是邊看書邊寫博客的,好了,接下來我們繼續吧。

無論如何,即時我現在明白了正則表達式不難,但是仍然還是把正則表達式寫得越簡單越好。

那麼下面來寫一個匹配數字的正則表達式吧

var myRegExp=/^-?\d+(?:\.\d*)?(?:e[+\-])?\d+)?$/i;
var url="-1.3e-3";
var result=myRegExp.test(url);//result為true

這上面的正則表達式的最後的 i 表示匹配字符串時忽略大小寫。那麼讓我們擴展一下:

  • 以i結尾:表示忽略字符串大小寫,都會匹配
  • 以g結尾: 表示全局的(匹配多次)。對於test方法不建議使用g,string的search方法會自動忽略g標識。
  • 以m結尾:多行($和^能匹配行結束符)

創建正則表達式的方式:

  • 最簡單的,就像我上面那麼玩的
    • var myRegExp=/^-?\d+$/i
  • 另外一種是使用RegExp構造器。Reg構造器適用於,必須在運行時動態生成正則表達式的情形。
    •   
      var myRegExp=new RegExp("\"(?:\\\\.|[^\\\\\\\"])*\"",'g');

       

    • RegExp的屬性
      • global:如果標識g被使用,值為true。
      • ignoreCase:如果標識i被使用,值為true。
      • lastIndex:下一次exec匹配開始的索引。初始值為0.
      • multiline:如果標識m被使用,值為true
      • source:正則表達式源碼文本
    • 用正則表達式字面量創造的RegExp對象,共享同一個單例。(我自己測了一下發現並非如此,所以這句話真實性有待確認)

關於構成正則表達式的元素

  • 分支:用|表示,兩個正則表達式可以用|並起來成為一個,如果字符串匹配由|分隔的兩個正則表達式任意一個,那麼這個選擇匹配。
  • 正則表達式匹配量詞,簡單來講就是匹配多少次
    • {3,6}表示會匹配3到6次 
    • *  等同於{0,}
    • +  等同於{1,}
    • ?  等同於{0,1}
  • ASCII碼特殊字符的匹配寫法
    • [!-\/:-@\[-'{-~]

      非常難看,且難懂,所以我的正則表達式啊,唉~~~

  • 正則表達式分組類型
    • 捕獲型:()
    • 非捕獲型:(?:)進行簡單的匹配,並不會捕獲所匹配的文本。會有微弱的性能優勢。
    • 向前正向匹配:(?=)   作者說這個特性和下面這個特性並非好的特性,所以,我已經決定開始忘掉了。
    • 向後負向匹配:(?!)
  • 需要加轉義字符的字符:\ / [ ]  (  )  ? + - * | . ^ s
  • 同時一些有趣的轉義字符
    • \f 換頁符
    • \n 換行符
    • \r  回車符
    • \t  制表符即tab
    • \u 允許指定一個Unicode字符來表示一個16進制的常量
    • \d 等同於[0-9],\D正好相反,等同於[^0-9]
    • \s 等同於[\f\n\r\t\u000B\u0020\u00A0\u2028\u2029].這是一個Unicode空白字符的不完全子集,\S正好相反
    • \w 等同於[0-9A-Z_a-z],\W正好相反,\W希望表示的是字母類但是它通常很難起作用。
    • 所以一個更簡單的字母類是[A-Za-z\u00C0-\u1FFF\u2800-\uFFFD],它包括所有Unicode字母和其他非字母字符。Unicode比這大的多,但是太龐大而低效了。所以用這個簡單的就好
    • \b 被指定為一個字邊界標識,方便對文本的字邊界進行匹配。然而他會用\w去找邊界,所以對多語言來說這是個不好的特性。
    • \1 \2 \3分別值的第1、2、3個分組所捕獲的文本的一個引用
      • 所以用此正則表達式可以用來搜索文本中是否存在重復的單詞隔著幾個空白字符挨在一起的情況:
        var doubledWord=/([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1/gi;

         

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved