正則表達式,又叫規則表達式。把人類世界的一些字符規則以計算機可以理解的語言表達出來。Javascript提供了一個對象RegExp(Regular Expression)來管理和正則表達式相關的一切。javascript
有兩種聲明正則對象的方法:html
其中,attributes表明該正則的屬性參數,可選值爲g, i, m,分別表明全局匹配,忽略大小寫,換行匹配。其中m在ECMAScript標準化以前不支持使用。前端
經常使用的正則匹配字符按功能能夠分爲「匹配字符」「匹配位置」和「量詞」。java
字符:git
位置:正則表達式
量詞:express
要想查找數字,字母或數字是很簡單的,由於已經有了對應這些字符集合的元字符,可是若是你想匹配沒有預約義元字符的字符集合(好比元音字母a,e,i,o,u),應該怎麼辦?數組
很簡單,你只須要在方括號裏列出它們就好了,像[aeiou]就匹配任何一個英文元音字母,[.?!]匹配標點符號(.或?或!)。前端工程師
咱們也能夠輕鬆地指定一個字符範圍,像[0-9]表明的含意與\d就是徹底一致的:一位數字;同理[a-z0-9A-Z_]也徹底等同於\w(若是隻考慮英文的話)。此外,最經常使用的還有檢測輸入是否含有中文,使用[\u4e00-\u9fa5]。測試
字符類還能夠用[^a]來匹配任何除了a之外的字符。
正則表達式裏的分枝條件指的是有幾種規則,若是知足其中任意一種規則都應該當成匹配,具體方法是用|把不一樣的規則分隔開。
\d{5}-\d{4}|\d{5}這個表達式用於匹配美國的郵政編碼。美國郵編的規則是5位數字,或者用連字號間隔的9位數字。之因此要給出這個例子是由於它能說明一個問題:使用分枝條件時,要注意各個條件的順序。若是你把它改爲\d{5}|\d{5}-\d{4}的話,那麼就只會匹配5位的郵編(以及9位郵編的前5位)。緣由是匹配分枝條件時,將會從左到右地測試每一個條件,若是知足了某個分枝的話,就不會去再管其它的條件了。
有時須要查找不屬於某個能簡單定義的字符類的字符。好比想查找除了數字之外,其它任意字符都行的狀況,這時須要用到反義:
若是咱們須要重複匹配多個字符,能夠用小括號將須要的部分括起,指定子表達式(分組)。使用小括號指定一個子表達式後,匹配這個子表達式的文本(也就是此分組捕獲的內容)能夠在表達式或其它程序中做進一步的處理。默認狀況下,每一個分組會自動擁有一個組號,規則是:從左向右,以分組的左括號爲標誌,第一個出現的分組的組號爲1,第二個爲2,以此類推。
好比咱們要匹配相似go go或kitty kitty的重複出現的字符,就可使用如下匹配方式:\b(\w+)\b\s+\1\b。
經常使用的分組語法以下:
由第二條,咱們能夠獲得上面正則的另外一種表現形式:\b(?<Word>\w+)\b\s+\k<Word>\b。
零寬斷言用於查找在前面或後面知足某種條件的字段(但不包括先後知足匹配的那部分),也就是說它們像\b,^,$那樣用於指定一個位置,這個位置應該知足必定的條件(即斷言),所以它們也被稱爲零寬斷言。
(?=exp)也叫零寬度正預測先行斷言,它斷言自身出現的位置的後面能匹配表達式exp。好比\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing之外的部分),如查找I'm singing while you're dancing.時,它會匹配sing和danc。
(?<=exp)也叫零寬度正回顧後發斷言,它斷言自身出現的位置的前面能匹配表達式exp。好比(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re之外的部分),例如在查找reading a book時,它匹配ading。
注:JS引擎不支持這種正則表達方式。由於這種方式效率不高,推薦使用分組進行匹配。
負向零寬斷言用於查找在前面或後面不知足某種條件的字段(但不包括先後知足匹配的那部分)。此處要與反義字符作區分。例如,若是咱們想查找這樣的單詞--它裏面出現了字母q,可是q後面跟的不是字母u,咱們能夠嘗試這樣:
\b\w*q[^u]\w*\b匹配包含後面不是字母u的字母q的單詞。可是若是多作測試(或者你思惟足夠敏銳,直接就觀察出來了),你會發現,若是q出如今單詞的結尾的話,像Iraq,Benq,這個表達式就會出錯。這是由於[^u]總要匹配一個字符,因此若是q是單詞的最後一個字符的話,後面的[^u]將會匹配q後面的單詞分隔符(多是空格,或者是句號或其它的什麼),後面的\w*\b將會匹配下一個單詞,因而\b\w*q[^u]\w*\b就能匹配整個Iraq fighting。負向零寬斷言能解決這樣的問題,由於它只匹配一個位置,並不消費任何字符。如今,咱們能夠這樣來解決這個問題:\b\w*q(?!u)\w*\b。
零寬度負預測先行斷言(?!exp),斷言此位置的後面不能匹配表達式exp。例如:\d{3}(?!\d)匹配三位數字,並且這三位數字的後面不能是數字;\b((?!abc)\w)+\b匹配不包含連續字符串abc的單詞。
同理,咱們能夠用(?<!exp),零寬度負回顧後發斷言來斷言此位置的前面不能匹配表達式exp:(?<![a-z])\d{7}匹配前面不是小寫字母的七位數字。
這有一個用於匹配沒有內聯樣式的HTML標籤中的內容(不匹配標籤):(?<=<(\w+)>).*(?=<\/\1>)。這個表達式最能表現零寬斷言的真正用途。
小括號的另外一種用途是經過語法(?#comment)來包含註釋。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。
正則有一個特色——貪婪。它會匹配儘量多的東西。好比當我想將<div><bold>標題</bold>文本</div>中的標籤用空格替換掉,若是使用/<.+>/則會使整段文本被替換,由於正則會匹配儘量多的字符。那麼應該如何讓正則匹配儘量少的字符呢?這時候就須要使用「懶惰匹配」。只須要在量詞(*+[2,4])後面加一個問號,就可讓正則匹配儘量少的字符。針對上面的例子就應該使用/<.+?>/。
ps: 本例也能夠用/<[^<>]+>/來實現。
var str = 'abcdef'; str.search('b'); // 1 str.substring(1,4) //"bcd" str.charAt(0); //"a" var str = 'abc-12-u-qw'; var arr = str.split('-'); alert(arr); //["abc", "12", "a", "qu"]
var str = 'abc 12 as23 1'; str.search(/\d/); //4 str.match(/\d+/g); //["12", "23", "1"] str.replace(/a/g, 'T'); // 'Tbc 12 Ts23 1'
ps: replace()與正則表達式應用實例——過濾敏感詞與提取HTML標籤內的純文本
在非全局匹配時,str.match(reg)和reg.exec(str)都能實現分組匹配,然而當進行全局匹配時,exec可以記錄上次匹配的索引,繼續進行匹配。此時一般結合循環使用,事例以下:
var s = 'aaalllsss0tAAAnnn999'; var re1 = /((\w)\2{2})(\w)\3{2}/g; var res; while(res=re1.exec(s)) { console.log("match result: " + res[1]}; console.log("re1.lastindex: " + re1.lastIndex); console.log("remain string: " + s.slice(re1.lastIndex)); }